Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow appending neighbor entries, which is useful with certain kernel drivers #61

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
33 changes: 30 additions & 3 deletions src/neighbour/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use futures::stream::StreamExt;

use netlink_packet_core::{
NetlinkMessage, NetlinkPayload, NLM_F_ACK, NLM_F_CREATE, NLM_F_EXCL,
NLM_F_REPLACE, NLM_F_REQUEST,
NLM_F_REPLACE, NLM_F_REQUEST, NLM_F_APPEND,
};
use netlink_packet_route::{
neighbour::{
Expand All @@ -22,6 +22,7 @@ pub struct NeighbourAddRequest {
handle: Handle,
message: NeighbourMessage,
replace: bool,
append: bool,
}

impl NeighbourAddRequest {
Expand All @@ -48,6 +49,7 @@ impl NeighbourAddRequest {
handle,
message,
replace: false,
append: false
}
}

Expand All @@ -68,6 +70,7 @@ impl NeighbourAddRequest {
handle,
message,
replace: false,
append: false
}
}

Expand Down Expand Up @@ -150,18 +153,42 @@ impl NeighbourAddRequest {
}
}

/// Append a new neighbor, useful with `add_bridge` to instruct it to
/// forward frames for broadcast/multicast destination MACs to multiple
/// destinations.
pub fn append(self) -> Self {
Self {
append: true,
..self
}
}

/// Execute the request.
pub async fn execute(self) -> Result<(), Error> {
let NeighbourAddRequest {
mut handle,
message,
replace,
append,
} = self;

let mut req =
NetlinkMessage::from(RouteNetlinkMessage::NewNeighbour(message));
let replace = if replace { NLM_F_REPLACE } else { NLM_F_EXCL };
req.header.flags = NLM_F_REQUEST | NLM_F_ACK | replace | NLM_F_CREATE;

let nl_msg_flags: u16;
// Append and replace are mutually exclusive here and based on my
// reading of thge kernel sources, NLM_F_EXCL is nonsensical to use
// with either NLM_F_REPLACE or NLM_F_APPEND. If both replace and
// append are set, replace instead.
if replace {
nl_msg_flags = NLM_F_REPLACE;
} else if append {
nl_msg_flags = NLM_F_APPEND;
} else {
nl_msg_flags = NLM_F_EXCL;
}

req.header.flags = NLM_F_REQUEST | NLM_F_ACK | nl_msg_flags | NLM_F_CREATE;

let mut response = handle.request(req)?;
while let Some(message) = response.next().await {
Expand Down