Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/grpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@ impl proto::Path {
Some(pos) => {
let name = &segment[..pos];
let mut keys = HashMap::new();
for kv in segment[pos..].split('[').filter(|s| !s.is_empty())
for kv in
segment[pos..].split('[').filter(|s| !s.is_empty())
{
let kv = kv.trim_end_matches(']');
if let Some(eq_pos) = kv.find('=') {
Expand Down
6 changes: 3 additions & 3 deletions src/internal_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2135,7 +2135,7 @@ pub fn cmd_show_bgp_neighbor(
let data =
fetch_data(session, proto::get_request::DataType::State, &xpath_req)?;

let xpath_routes = format!("{}/route", &xpath_req);
let xpath_routes = format!("{}/route", xpath_req);

let output = session.writer();

Expand Down Expand Up @@ -2461,12 +2461,12 @@ pub fn cmd_clear_bgp_neighbor(
"soft-in" => "soft-inbound",
op => op,
};
let xpath = format!("{}/{}", &xpath, operation);
let xpath = format!("{}/{}", xpath, operation);
clear_req.new_path(&xpath, None, false).unwrap();
}

if neighbor.is_some() {
let xpath = format!("{}/holo-bgp:remote-addr", &xpath);
let xpath = format!("{}/holo-bgp:remote-addr", xpath);
clear_req
.new_path(&xpath, neighbor.as_deref(), false)
.unwrap();
Expand Down
39 changes: 37 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,25 @@ impl Cli {

// ===== global functions =====

// Compiles a YANG context that was created with `LY_CTX_EXPLICIT_COMPILE`.
//
// yang5 0.2 exposes neither a safe `compile()` wrapper nor a `from_raw()`
// constructor, so the compiled schema has to be triggered through the raw
// libyang pointer.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to open a PR for the yang5 crate to implement that.

fn compile_context(yang_ctx: Context) -> Context {
let raw = yang_ctx.into_raw();
let ret = unsafe { yang5::ffi::ly_ctx_compile(raw) };
assert_eq!(
ret,
yang5::ffi::LY_ERR::LY_SUCCESS,
"failed to compile YANG context"
);
// SAFETY: `Context` is a newtype wrapping exactly this `*mut ly_ctx`.
// Rebuilding it from the pointer returned by `into_raw()` re-establishes
// ownership so the context is still freed on drop.
unsafe { std::mem::transmute::<*mut yang5::ffi::ly_ctx, Context>(raw) }
}

fn read_config_file(mut cli: Cli, path: &str) {
// Enter configuration mode.
let mode = CommandMode::Configure { nodes: vec![] };
Expand Down Expand Up @@ -242,8 +261,19 @@ fn main() {
};

// Initialize YANG context.
//
// Defer schema compilation with `LY_CTX_EXPLICIT_COMPILE`. Without it,
// libyang recompiles the whole context after *every* `load_module()` call;
// with ~75 modules advertised by holod that quadratic cost dominates
// startup (~0.5 s), which is paid on every single one-shot (`-c`)
// invocation. Instead, load all modules first and compile the context once
// (see `compile_context()` after the module load below).
let mut yang_ctx = Context::new(
ContextFlags::NO_YANGLIBRARY | ContextFlags::PREFER_SEARCHDIRS,
ContextFlags::NO_YANGLIBRARY
| ContextFlags::PREFER_SEARCHDIRS
| ContextFlags::from_bits_retain(
yang5::ffi::LY_CTX_EXPLICIT_COMPILE,
),
)
.unwrap();

Expand All @@ -259,8 +289,13 @@ fn main() {
// Set YANG search directory.
yang_ctx.set_searchdir(YANG_MODULES_DIR).unwrap();

// Load YANG modules.
// Load YANG modules (parsed but not yet compiled, see EXPLICIT_COMPILE
// above).
grpc_client.load_modules(grpc_addr, &mut yang_ctx);

// Compile the whole schema in a single pass now that every module has been
// loaded.
let yang_ctx = compile_context(yang_ctx);
YANG_CTX.set(Arc::new(yang_ctx)).unwrap();

// Initialize CLI master structure.
Expand Down
Loading