Skip to content

Add support for parsing some FreeBSD specific attributes - #221

Open
bigsaltyfishes wants to merge 16 commits into
rust-netlink:mainfrom
bigsaltyfishes:main
Open

Add support for parsing some FreeBSD specific attributes#221
bigsaltyfishes wants to merge 16 commits into
rust-netlink:mainfrom
bigsaltyfishes:main

Conversation

@bigsaltyfishes

@bigsaltyfishes bigsaltyfishes commented Jan 5, 2026

Copy link
Copy Markdown
  • IFA_FREEBSD (Conficts with IFA_PROTO in FreeBSD)
  • RTA_RTFLAGS, RTA_KNH_ID and RTA_WEIGHT
  • IFLA_FREEBSD
  • NDA_FREEBSD
  • STATS64 (Structure is different)
  • FreeBSD's LinkLayerType
  • Unit tests for FreeBSD (Due to difference of structure, most of current unit tests won't build, need to disable them on FreeBSD)
  • Add more link InfoKind.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @bigsaltyfishes, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the netlink-packet-route crate by integrating support for several FreeBSD-specific Netlink attributes. It introduces new modules and data types tailored for FreeBSD's network configuration, allowing the library to accurately interpret and construct platform-specific address and route messages. The changes are carefully isolated using conditional compilation to maintain cross-platform compatibility.

Highlights

  • FreeBSD Address Attributes: Introduced support for the IFA_FREEBSD attribute in address messages, which is conditionally compiled for FreeBSD targets. This includes new IfaFlags for IPv6 interface flags, defining specific states like Anycast, Tentative, and Deprecated.
  • FreeBSD Route Attributes: Added parsing and emission support for FreeBSD-specific route attributes: RTA_RTFLAGS, RTA_KNH_ID (kernel nexthop ID), and RTA_WEIGHT (path weight). This also includes a new RtFlags bitflag structure to represent various FreeBSD route flags.
  • Platform-Specific Implementation: All new attributes and their associated data structures are implemented using Rust's #[cfg(target_os = "freebsd")] attribute, ensuring that these FreeBSD-specific features are only included when compiling for the FreeBSD operating system.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request adds support for parsing FreeBSD-specific netlink attributes for network addresses and routes. The changes are well-structured, using conditional compilation to isolate the FreeBSD-specific logic. I've identified one critical issue that would break compilation on non-FreeBSD platforms, and a few medium-severity issues related to code style and potential compiler warnings. Addressing these points will improve the robustness and clarity of the code.

Comment thread src/address/attribute.rs
Comment thread src/address/freebsd.rs
Comment thread src/route/attribute.rs
Comment thread src/route/attribute.rs
Comment thread src/route/attribute.rs
@bigsaltyfishes
bigsaltyfishes force-pushed the main branch 6 times, most recently from a1ddf7d to a6f5446 Compare January 6, 2026 11:35
@bigsaltyfishes bigsaltyfishes changed the title DRAFT: Add support for parsing FreeBSD specific attributes Add support for parsing some FreeBSD specific attributes Jan 6, 2026
@bigsaltyfishes
bigsaltyfishes marked this pull request as ready for review January 6, 2026 11:38
@codecov

codecov Bot commented Jan 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.92%. Comparing base (1fb4bd7) to head (a6f5446).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #221      +/-   ##
==========================================
- Coverage   68.10%   67.92%   -0.18%     
==========================================
  Files         144      140       -4     
  Lines       10103     9959     -144     
==========================================
- Hits         6881     6765     -116     
+ Misses       3222     3194      -28     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cathay4t cathay4t left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  • Rename the FreeBSD to more specific name.
  • The Nla::kind is wrong.
  • Do not use magic number. Hard to maintain and verify in BSD kernel code.
  • Unit test is mandatory. Google says tcpdump -i lo0 -n 'netlink' can capture netlink message in FreeBSD. Without emit and parse test, I cannot tell whether you are doing correct or not.
  • Please include short commit message indicate which FreeBSD kernel file is handling these attribute so developer could review.

Comment thread src/address/freebsd.rs Outdated

#[non_exhaustive]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum FreeBSD {

@cathay4t cathay4t Jan 6, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How about FreeBsdAddressAttribute to be more specific?

Comment thread src/address/freebsd.rs Outdated
let value = parse_u32(buf.value())
.context("failed to parse IFA_FREEBSD attribute value")?;
match buf.value_type() {
1 => Ok(FreeBSD::Vhid(value)),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please change magic number to constant.

Comment thread src/address/freebsd.rs Outdated

impl Nla for FreeBSD {
fn kind(&self) -> u16 {
11

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The kind here is wrong.

It should be kind of VhId, IfaFlags and etc.

Comment thread src/address/freebsd.rs
Comment thread src/address/freebsd.rs Outdated
#[non_exhaustive]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum FreeBSD {
Unspecified,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Remove this unless freebsd code is using this unspec in real environment instead of place holder.

Comment thread src/link/freebsd.rs Outdated
#[non_exhaustive]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum FreeBSD {
Unspecified,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Remove unspec if it is a place holder.

Comment thread src/link/freebsd.rs Outdated
cap_bit_size: u32,
supported_caps: (IfCapFlags, IfCap2Flags),
active_caps: (IfCapFlags, IfCap2Flags),
},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Add Other(DefaultNla) for future FreeBSD kernel.

Comment thread src/link/freebsd.rs Outdated
IfCaps {
cap_bit_size: u32,
supported_caps: (IfCapFlags, IfCap2Flags),
active_caps: (IfCapFlags, IfCap2Flags),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Create a struct for this.

Comment thread src/link/freebsd.rs Outdated
}

match buf.value_type() {
2 => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use constant instead of magic number.

Comment thread src/link/freebsd.rs Outdated

impl Nla for FreeBSD {
fn kind(&self) -> u16 {
64

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It should be kind of FreeBSD::IfCaps and etc.

@bigsaltyfishes
bigsaltyfishes force-pushed the main branch 4 times, most recently from 6066615 to 7119fa5 Compare January 7, 2026 11:24
@bigsaltyfishes

Copy link
Copy Markdown
Author

I have modified and added unit tests. Because some constant and structure definitions in FreeBSD differ significantly from those in Linux, I have added the missing constants and different structures.

@cathay4t

cathay4t commented Feb 2, 2026

Copy link
Copy Markdown
Member

@bigsaltyfishes Could you include an example code into /examples folder for me to run in FreeBSD env? That could explains the purpose of this PR and easy for me to try out.

@cathay4t

cathay4t commented Mar 2, 2026

Copy link
Copy Markdown
Member

@bigsaltyfishes any comments?

@bigsaltyfishes

Copy link
Copy Markdown
Author

Added Examples and rebased, need to be tested on Linux.

@bigsaltyfishes

Copy link
Copy Markdown
Author

@cathay4t Examples added, since rust's libc does not support netlink on FreeBSD, I added a ffi for examples.

@cathay4t

Copy link
Copy Markdown
Member

Great. Let me install a FreeBSD and try it out.

@cathay4t

Copy link
Copy Markdown
Member

@bigsaltyfishes I got failure when running this command in FreeBSD 15:

cargo run --example  dump_packet_links

Error is:

    ::: examples/freebsd/mod.rs:13:1
     |
  13 | pub struct NetlinkSocket(OwnedFd);
     | ------------------------ method `write_all` not found for this struct
    --> examples/dump_packet_links.rs:105:12
     |
 105 |     socket.write_all(&buf[..]).unwrap();
     |            ^^^^^^^^^
     |
     = help: items from traits can only be used if the trait is in scope
help: trait `Write` which provides `write_all` is implemented but not in scope; perhaps you want to import it
     |
   3 + use std::io::Write;
     |
help: there is a method `write` with a similar name
     |
 105 -     socket.write_all(&buf[..]).unwrap();
 105 +     socket.write(&buf[..]).unwrap();
     |

error[E0599]: no method named `read` found for struct `NetlinkSocket` in the current scope
   --> examples/dump_packet_links.rs:113:27
    |
113 |         let size = socket.read(&mut &mut receive_buffer[..]).unwrap();
    |                           ^^^^ method not found in `NetlinkSocket`
    |
   ::: /usr/local/lib/rustlib/src/rust/library/std/src/io/mod.rs:813:8
    |
813 |     fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
    |        ---- the method is available for `NetlinkSocket` here
    |
   ::: examples/freebsd/mod.rs:13:1
    |
 13 | pub struct NetlinkSocket(OwnedFd);
    | ------------------------ method `read` not found for this struct
    |
    = help: items from traits can only be used if the trait is in scope
help: trait `Read` which provides `read` is implemented but not in scope; perhaps you want to import it
    |
  3 + use std::io::Read;

Due to the difference of contant and support features, some tests may failed.

Signed-off-by: molyuu <bigsaltyfishes@gmail.com>
As defined at https://github.com/freebsd/freebsd-src/blob/release/15.0.0-p1/sys/netlink/route/interface.h#L209-L235, there are no `rx_otherhost_dropped` filed in `Stats64`.

Signed-off-by: molyuu <bigsaltyfishes@gmail.com>
Add missing kinds and disable Linux-specific ones for FreeBSD.
Currently, only Vlan kind supports `IFLA_INFO_DATA`.

Reference: https://github.com/freebsd/freebsd-src/blob/main/sys/net/if_vlan.c#L1213-L1296

Signed-off-by: molyuu <bigsaltyfishes@gmail.com>
Signed-off-by: bigsaltyfishes <bigsaltyfishes@gmail.com>
Signed-off-by: bigsaltyfishes <bigsaltyfishes@gmail.com>
…FI example

Signed-off-by: molyuu <bigsaltyfishes@gmail.com>
Signed-off-by: molyuu <bigsaltyfishes@gmail.com>
Signed-off-by: molyuu <bigsaltyfishes@gmail.com>
…tests

- Some test data is not supported on FreeBSD, since the tests consistently fail on this platform, just disable them for FreeBSD.

Signed-off-by: molyuu <bigsaltyfishes@gmail.com>
Signed-off-by: molyuu <bigsaltyfishes@gmail.com>
@bigsaltyfishes

Copy link
Copy Markdown
Author

@cathay4t Okay, my fault during testing on Linux. I've revert changes. Should work now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants