#![cfg(target_pointer_width = "64")]
pub mod xfrm {
pub const USERPOLICY_INFO: usize = 168;
pub const USERPOLICY_ID: usize = 64;
pub const USERSA_INFO: usize = 224;
pub const SELECTOR: usize = 56;
pub const LIFETIME_CFG: usize = 64;
pub const LIFETIME_CUR: usize = 32;
pub const USER_TMPL: usize = 64;
}
pub mod nft_verdict {
pub const NF_DROP: i32 = 0;
pub const NF_ACCEPT: i32 = 1;
pub const NFT_CONTINUE: i32 = -1;
pub const NFT_BREAK: i32 = -2;
pub const NFT_JUMP: i32 = -3;
pub const NFT_GOTO: i32 = -4;
pub const NFT_RETURN: i32 = -5;
}
pub const DEVLINK_MCGRP_CONFIG_NAME: &str = "config";
pub mod nf_hook {
pub const PRE_ROUTING: u32 = 0;
pub const LOCAL_IN: u32 = 1;
pub const FORWARD: u32 = 2;
pub const LOCAL_OUT: u32 = 3;
pub const POST_ROUTING: u32 = 4;
pub const INET_INGRESS: u32 = 5;
pub const NETDEV_INGRESS: u32 = 0;
pub const NETDEV_EGRESS: u32 = 1;
}
#[cfg(test)]
mod tests {
use super::*;
use std::mem::size_of;
#[test]
fn xfrm_userpolicy_info_size_matches_kernel() {
assert_eq!(
size_of::<crate::netlink::xfrm::XfrmUserpolicyInfo>(),
xfrm::USERPOLICY_INFO,
"XfrmUserpolicyInfo: kernel expects {} bytes (Plan 204 C2)",
xfrm::USERPOLICY_INFO,
);
}
#[test]
fn xfrm_userpolicy_id_size_matches_kernel() {
assert_eq!(
size_of::<crate::netlink::xfrm::XfrmUserpolicyId>(),
xfrm::USERPOLICY_ID,
"XfrmUserpolicyId: kernel expects {} bytes (Plan 204 C3)",
xfrm::USERPOLICY_ID,
);
}
#[test]
fn xfrm_usersa_info_size_matches_kernel() {
assert_eq!(
size_of::<crate::netlink::xfrm::XfrmUsersaInfo>(),
xfrm::USERSA_INFO,
);
}
#[test]
fn xfrm_selector_size_matches_kernel() {
assert_eq!(
size_of::<crate::netlink::xfrm::XfrmSelector>(),
xfrm::SELECTOR,
);
}
#[test]
fn xfrm_lifetime_cfg_size_matches_kernel() {
assert_eq!(
size_of::<crate::netlink::xfrm::XfrmLifetimeCfg>(),
xfrm::LIFETIME_CFG,
);
}
#[test]
fn xfrm_lifetime_cur_size_matches_kernel() {
assert_eq!(
size_of::<crate::netlink::xfrm::XfrmLifetimeCur>(),
xfrm::LIFETIME_CUR,
);
}
#[test]
fn xfrm_user_tmpl_size_matches_kernel() {
assert_eq!(
size_of::<crate::netlink::xfrm::XfrmUserTmpl>(),
xfrm::USER_TMPL,
);
}
#[test]
fn nft_verdict_constants_match_kernel_uapi() {
use crate::netlink::nftables::{
NF_ACCEPT, NF_DROP, NFT_BREAK, NFT_CONTINUE, NFT_GOTO, NFT_JUMP, NFT_RETURN,
};
assert_eq!(NF_DROP, nft_verdict::NF_DROP);
assert_eq!(NF_ACCEPT, nft_verdict::NF_ACCEPT);
assert_eq!(NFT_CONTINUE, nft_verdict::NFT_CONTINUE);
assert_eq!(
NFT_BREAK,
nft_verdict::NFT_BREAK,
"NFT_BREAK was missing in nlink pre-0.19 (Plan 204 C1)"
);
assert_eq!(
NFT_JUMP,
nft_verdict::NFT_JUMP,
"NFT_JUMP was -2 (= NFT_BREAK) pre-0.19 (Plan 204 C1)"
);
assert_eq!(
NFT_GOTO,
nft_verdict::NFT_GOTO,
"NFT_GOTO was -3 (= NFT_JUMP) pre-0.19 (Plan 204 C1)"
);
assert_eq!(NFT_RETURN, nft_verdict::NFT_RETURN);
}
#[test]
fn devlink_mcast_group_name_matches_kernel_uapi() {
use crate::netlink::genl::devlink::DEVLINK_MCGRP_NAME;
assert_eq!(
DEVLINK_MCGRP_NAME, DEVLINK_MCGRP_CONFIG_NAME,
"DEVLINK_MCGRP_NAME was \"devlink\" pre-0.19 (Plan 204 C4); \
kernel registers it as \"config\"."
);
}
#[test]
fn nft_hook_variants_match_kernel_uapi() {
use crate::netlink::nftables::Hook;
assert_eq!(Hook::Prerouting.to_u32(), nf_hook::PRE_ROUTING);
assert_eq!(Hook::Input.to_u32(), nf_hook::LOCAL_IN);
assert_eq!(Hook::Forward.to_u32(), nf_hook::FORWARD);
assert_eq!(Hook::Output.to_u32(), nf_hook::LOCAL_OUT);
assert_eq!(Hook::Postrouting.to_u32(), nf_hook::POST_ROUTING);
assert_eq!(
Hook::InetIngress.to_u32(),
nf_hook::INET_INGRESS,
"InetIngress was Hook::Ingress=0 pre-0.19 (Plan 211 M1); \
kernel expects NF_INET_INGRESS=5"
);
assert_eq!(Hook::NetdevIngress.to_u32(), nf_hook::NETDEV_INGRESS);
assert_eq!(Hook::NetdevEgress.to_u32(), nf_hook::NETDEV_EGRESS);
}
#[test]
fn nft_hook_is_valid_for_family_disambiguates_correctly() {
use crate::netlink::nftables::{Family, Hook};
assert!(Hook::NetdevIngress.is_valid_for_family(Family::Netdev));
assert!(!Hook::NetdevIngress.is_valid_for_family(Family::Inet));
assert!(Hook::InetIngress.is_valid_for_family(Family::Inet));
assert!(!Hook::InetIngress.is_valid_for_family(Family::Netdev));
assert!(Hook::Prerouting.is_valid_for_family(Family::Inet));
assert!(Hook::Forward.is_valid_for_family(Family::Ip6));
assert!(!Hook::Prerouting.is_valid_for_family(Family::Netdev));
assert!(Hook::NetdevEgress.is_valid_for_family(Family::Netdev));
assert!(!Hook::NetdevEgress.is_valid_for_family(Family::Bridge));
}
}