use clap::Parser;
use log::LevelFilter;
use log::{error, info};
use misc::synthesize;
use syslog::{BasicLogger, Facility, Formatter3164};
mod interface;
mod misc;
mod netns;
const MYSELF: &str = "swan-updown";
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct SwanUpdown {
#[arg(short, long, value_name = "netns")]
netns: Option<String>,
#[arg(short, long, value_name = "prefix")]
prefix: Option<String>,
#[arg(long, action = clap::ArgAction::SetTrue)]
to_stdout: bool,
#[arg(short, long, action = clap::ArgAction::Count)]
debug: u8,
}
#[tokio::main]
async fn main() -> Result<(), ()> {
let args = SwanUpdown::parse();
let my_loglevel = match args.debug {
0 => LevelFilter::Error,
1 => LevelFilter::Warn,
2 => LevelFilter::Info,
_ => LevelFilter::Debug,
};
if args.to_stdout {
env_logger::init();
} else {
let formatter = Formatter3164 {
facility: Facility::LOG_USER,
hostname: None,
process: MYSELF.into(),
pid: 42,
};
let logger =
syslog::unix(formatter).map_err(|e| error!("failed to create logger: {}", e))?;
match log::set_boxed_logger(Box::new(BasicLogger::new(logger))) {
Ok(_) => log::set_max_level(my_loglevel),
Err(_) => return Err(()),
};
}
let if_prefix = args.prefix.unwrap_or_else(|| "swan".into());
let trigger = misc::find_env("PLUTO_VERB")?;
let conn_if_id: u32 = misc::find_env("PLUTO_IF_ID_IN")?
.parse::<u32>()
.map_err(|e| error! {"parse if_id failed: {}", e})?;
let handle = misc::netlink_handle()?;
if trigger.starts_with("up-client") {
interface::new_xfrm(
&handle,
&misc::synthesize(&if_prefix, conn_if_id),
conn_if_id,
)
.await?;
if let Some(netns_name) = args.netns {
interface::move_to_netns(
&handle,
&misc::synthesize(&if_prefix, conn_if_id),
&netns_name,
)
.await?;
}
} else if trigger.starts_with("down-client") {
match args.netns {
Some(netns_name) => {
interface::del_in_netns(&synthesize(&if_prefix, conn_if_id), &netns_name).await?
}
None => interface::del(&handle, &synthesize(&if_prefix, conn_if_id)).await?,
}
} else {
info!("No action is taken for PLUTO_VERB {}", trigger)
}
Ok(())
}