Skip to content

Commit 147802f

Browse files
[#158]: added shared hashmap to store tracked veth (TRACKED_VETH). The shared map is used to store the veth names and the status (attached or not) during the startup
1 parent 01c63c4 commit 147802f

File tree

2 files changed

+66
-13
lines changed

2 files changed

+66
-13
lines changed

core/src/components/conntracker/src/data_structures.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub struct ConnArray {
4747
// pid: kernel process ID
4848
//
4949

50-
#[repr(C,packed)]
50+
#[repr(C, packed)]
5151
#[derive(Clone, Copy)]
5252
pub struct VethLog {
5353
pub name: [u8; 16], // 16 bytes: veth interface name
@@ -94,9 +94,13 @@ pub static mut CONNTRACKER: LruPerCpuHashMap<ConnArray, u8> =
9494
pub static mut VETH_EVENTS: PerfEventArray<VethLog> = PerfEventArray::new(0);
9595

9696
#[map(name = "Blocklist", pinning = "by_name")]
97-
pub static mut BLOCKLIST: HashMap<[u8; 4], [u8; 4]> =
98-
HashMap::<[u8; 4], [u8; 4]>::with_max_entries(1024, 0);
97+
pub static mut BLOCKLIST: HashMap<[u8; 4], [u8; 4]> = HashMap::with_max_entries(1024, 0);
9998
//here i need to pass an address like this: [135,171,168,192]
10099

101100
#[map(name = "TcpPacketRegistry", pinning = "by_name")]
102101
pub static mut PACKET_REGISTRY: PerfEventArray<TcpPacketRegistry> = PerfEventArray::new(0);
102+
103+
#[map(name = "tracked_veth", pinning = "by_name")]
104+
// This map takes a registry of tracked veth interfaces
105+
// The maximum number of characters is 16 of type u8
106+
pub static mut TRACKED_VETH: HashMap<[u8; 16], [u8; 8]> = HashMap::with_max_entries(1024, 0);

core/src/components/identity/src/main.rs

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ mod service_discovery;
1414
use crate::helpers::get_veth_channels;
1515
use aya::{
1616
Ebpf,
17-
programs::{SchedClassifier, TcAttachType, tc::SchedClassifierLinkId},
17+
maps::{Map, MapData},
18+
programs::{SchedClassifier, TcAttachType},
1819
util::online_cpus,
1920
};
2021

@@ -36,7 +37,7 @@ use std::{
3637

3738
use anyhow::{Context, Ok, anyhow};
3839

39-
use std::collections::HashMap;
40+
//use std::collections::HashMap;
4041
use tokio::{fs, signal};
4142
use tracing::{error, info};
4243

@@ -49,7 +50,7 @@ async fn main() -> Result<(), anyhow::Error> {
4950
info!("fetching data");
5051

5152
// To Store link_ids they can be used to detach tc
52-
let link_ids = Arc::new(Mutex::new(HashMap::<String, SchedClassifierLinkId>::new()));
53+
//let mut link_ids = HashMap::<String, SchedClassifierLinkId>::new();
5354

5455
//init conntracker data path
5556
let bpf_path =
@@ -67,6 +68,7 @@ async fn main() -> Result<(), anyhow::Error> {
6768
"veth_identity_map".to_string(),
6869
"TcpPacketRegistry".to_string(),
6970
"Blocklist".to_string(),
71+
"tracked_veth".to_string(),
7072
];
7173
match init_bpf_maps(bpf.clone(), map_data) {
7274
std::result::Result::Ok(bpf_maps) => {
@@ -90,8 +92,8 @@ async fn main() -> Result<(), anyhow::Error> {
9092
}
9193

9294
{
93-
init_tc_classifier(bpf.clone(), interfaces, link_ids.clone()).await.context(
94-
"An error occured during the execution of attach_bpf_program function"
95+
init_tc_classifier(bpf.clone(), interfaces).await.context(
96+
"An error occured during the execution of attach_bpf_program function",
9597
)?;
9698
}
9799
{
@@ -120,10 +122,10 @@ async fn main() -> Result<(), anyhow::Error> {
120122
}
121123

122124
//attach the tc classifier program to a vector of interfaces
125+
// TODO: consider to create a load schedule classifier in the common functions
123126
async fn init_tc_classifier(
124127
bpf: Arc<Mutex<Ebpf>>,
125128
ifaces: Vec<String>,
126-
link_ids: Arc<Mutex<HashMap<String, SchedClassifierLinkId>>>,
127129
) -> Result<(), anyhow::Error> {
128130
//this funtion initialize the tc classifier program
129131
info!("Loading programs");
@@ -138,21 +140,68 @@ async fn init_tc_classifier(
138140
.try_into()
139141
.context("Failed to init SchedClassifier program")?;
140142

143+
// load classifier program
144+
141145
program
142146
.load()
143147
.context("Failed to load identity_classifier program")?;
144148

149+
// attach program only to desired interfaces. We can skip the dock0,tunl0,lo and eth0 interface
150+
// we also save the interfaces to a BPF_HASH_MAP to easily monitor the interfaces using the agent
151+
152+
// decleare link_ids HashMap which is a shared hashmap between kernel and userspace
153+
// Link_ids hashmap has type of HashMap<[u8; 16], [u8; 8]>. The key is the program name and the value is the state
154+
155+
// at this point the pinning is already successfull so we can invoque the maps from the pin
156+
157+
let link_ids_mapdata = MapData::from_pin("/sys/fs/bpf/maps/tracked_veth")
158+
.map_err(|e| anyhow!("Cannot return link_ids_mapdata. Reason: {}", e))?;
159+
160+
let link_ids_map = Map::HashMap(link_ids_mapdata);
161+
162+
let mut link_ids: aya::maps::HashMap<MapData, [u8; 16], [u8; 8]> =
163+
aya::maps::HashMap::try_from(link_ids_map).map_err(|e| {
164+
anyhow!(
165+
"Cannot create link_ids HashMap from link_ids_map. Reason:{}",
166+
e
167+
)
168+
})?;
169+
145170
for interface in ifaces {
146171
match program.attach(&interface, TcAttachType::Ingress) {
147172
std::result::Result::Ok(link_id) => {
148173
info!(
149174
"Program 'identity_classifier' attached to interface {}",
150175
interface
151176
);
152-
let mut map = link_ids
153-
.lock()
154-
.map_err(|e| anyhow::anyhow!("Cannot get value from lock. Reason: {}", e))?;
155-
map.insert(interface.clone(), link_id);
177+
let interface_bytes = interface.as_bytes();
178+
179+
let mut if_bytes = [0u8; 16];
180+
181+
// to set the len compare the interface_bytes.len() with the if_bytes.len() [16] and take the minimum
182+
// if we have interface_bytes.len() < than 16 we set the len
183+
let len = interface_bytes.len().min(if_bytes.len());
184+
185+
// now we can copy the bytes from the slice into the if_bytes variable
186+
if_bytes[..len].copy_from_slice(&interface_bytes[..len]);
187+
188+
// we compute the same process for the state_bytes
189+
let mut state_bytes = [0u8; 8];
190+
let state = b"attached"; // prints "attached" as [u8;8] sequence of bytes
191+
let state_len = state.len().min(state_bytes.len());
192+
state_bytes[..state_len].copy_from_slice(&state[..state_len]);
193+
194+
match link_ids.insert(if_bytes, state_bytes, 0) {
195+
std::result::Result::Ok(_) => {
196+
info!("Veth interface {} added into map", &interface);
197+
}
198+
Err(e) => {
199+
error!(
200+
"Cannot add Veth interface {} into map. Reason: {}",
201+
&interface, e
202+
);
203+
}
204+
}
156205
}
157206
Err(e) => error!(
158207
"Error attaching program to interface {}: {:?}",

0 commit comments

Comments
 (0)