mirror of
https://github.com/containers/netavark.git
synced 2026-02-05 06:45:56 +01:00
The existing `netlink.rs` was specific to `NETLINK_ROUTE`. To prepare for adding `NETLINK_NETFILTER` support for conntrack, this commit refactors the netlink socket implementation to be generic. - A new generic `Socket<P>` is introduced in `src/network/netlink.rs` to handle common send/receive logic. - All routing-specific code, types, and functions are moved to a new `src/network/netlink_route.rs`, which now uses `Socket<NetlinkRoute>`. - All imports and type signatures across the codebase have been updated to use this new structure. This is a pure refactoring with no functional changes. Signed-off-by: Shivang K Raghuvanshi <shivangraghuvanshi2005@gmail.com>
112 lines
3.2 KiB
Rust
112 lines
3.2 KiB
Rust
//! This is just an example plugin, do not use it in production!
|
|
|
|
use std::{collections::HashMap, os::fd::AsFd};
|
|
|
|
use netavark::{
|
|
network::{
|
|
core_utils::{open_netlink_sockets, CoreUtils},
|
|
netlink_route, types,
|
|
},
|
|
new_error,
|
|
plugin::{Info, Plugin, PluginExec, API_VERSION},
|
|
};
|
|
use netlink_packet_route::{address::AddressAttribute, link::LinkAttribute};
|
|
|
|
fn main() {
|
|
let info = Info::new("0.1.0-dev".to_owned(), API_VERSION.to_owned(), None);
|
|
|
|
PluginExec::new(Exec {}, info).exec();
|
|
}
|
|
|
|
struct Exec {}
|
|
|
|
impl Plugin for Exec {
|
|
fn create(
|
|
&self,
|
|
network: types::Network,
|
|
) -> Result<types::Network, Box<dyn std::error::Error>> {
|
|
if network.network_interface.as_deref().unwrap_or_default() == "" {
|
|
return Err(new_error!("no network interface is specified"));
|
|
}
|
|
|
|
Ok(network)
|
|
}
|
|
|
|
fn setup(
|
|
&self,
|
|
netns: String,
|
|
opts: types::NetworkPluginExec,
|
|
) -> Result<types::StatusBlock, Box<dyn std::error::Error>> {
|
|
let (mut host, netns) = open_netlink_sockets(&netns)?;
|
|
|
|
let name = opts.network.network_interface.unwrap_or_default();
|
|
|
|
let link = host
|
|
.netlink
|
|
.get_link(netlink_route::LinkID::Name(name.clone()))?;
|
|
|
|
let mut mac_address = String::from("");
|
|
for nla in link.attributes {
|
|
if let LinkAttribute::Address(ref addr) = nla {
|
|
mac_address = CoreUtils::encode_address_to_hex(addr);
|
|
}
|
|
}
|
|
|
|
let addresses = host.netlink.dump_addresses(None)?;
|
|
let mut subnets = Vec::new();
|
|
for address in addresses {
|
|
if address.header.index == link.header.index {
|
|
for nla in address.attributes {
|
|
if let AddressAttribute::Address(ip) = &nla {
|
|
let net = ipnet::IpNet::new(*ip, address.header.prefix_len)?;
|
|
subnets.push(types::NetAddress {
|
|
gateway: None,
|
|
ipnet: net,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
host.netlink
|
|
.set_link_ns(link.header.index, netns.file.as_fd())?;
|
|
|
|
// interfaces map, but we only ever expect one, for response
|
|
let mut interfaces: HashMap<String, types::NetInterface> = HashMap::new();
|
|
|
|
let interface = types::NetInterface {
|
|
mac_address,
|
|
subnets: Option::from(subnets),
|
|
};
|
|
interfaces.insert(name, interface);
|
|
|
|
// StatusBlock response
|
|
let response = types::StatusBlock {
|
|
dns_server_ips: None,
|
|
dns_search_domains: None,
|
|
interfaces: Some(interfaces),
|
|
};
|
|
|
|
Ok(response)
|
|
}
|
|
|
|
fn teardown(
|
|
&self,
|
|
netns: String,
|
|
opts: types::NetworkPluginExec,
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
// on teardown revert what was done in setup
|
|
let (host, mut netns) = open_netlink_sockets(&netns)?;
|
|
|
|
let name = opts.network.network_interface.unwrap_or_default();
|
|
|
|
let link = netns.netlink.get_link(netlink_route::LinkID::Name(name))?;
|
|
|
|
netns
|
|
.netlink
|
|
.set_link_ns(link.header.index, host.file.as_fd())?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|