#![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 mod xfrm_msg_type {
pub const XFRM_MSG_NEWSA: u16 = 16;
pub const XFRM_MSG_DELSA: u16 = 17;
pub const XFRM_MSG_GETSA: u16 = 18;
pub const XFRM_MSG_NEWPOLICY: u16 = 19;
pub const XFRM_MSG_DELPOLICY: u16 = 20;
pub const XFRM_MSG_GETPOLICY: u16 = 21;
pub const XFRM_MSG_ALLOCSPI: u16 = 22;
pub const XFRM_MSG_ACQUIRE: u16 = 23;
pub const XFRM_MSG_EXPIRE: u16 = 24;
pub const XFRM_MSG_UPDPOLICY: u16 = 25;
pub const XFRM_MSG_UPDSA: u16 = 26;
pub const XFRM_MSG_POLEXPIRE: u16 = 27;
pub const XFRM_MSG_FLUSHSA: u16 = 28;
pub const XFRM_MSG_FLUSHPOLICY: u16 = 29;
pub const XFRM_MSG_NEWAE: u16 = 30;
pub const XFRM_MSG_GETAE: u16 = 31;
}
pub mod xfrm_attr {
pub const XFRMA_ALG_AUTH: u16 = 1;
pub const XFRMA_ALG_CRYPT: u16 = 2;
pub const XFRMA_ALG_COMP: u16 = 3;
pub const XFRMA_ENCAP: u16 = 4;
pub const XFRMA_TMPL: u16 = 5;
pub const XFRMA_SA: u16 = 6;
pub const XFRMA_POLICY: u16 = 7;
pub const XFRMA_SEC_CTX: u16 = 8;
pub const XFRMA_LTIME_VAL: u16 = 9;
pub const XFRMA_REPLAY_VAL: u16 = 10;
pub const XFRMA_REPLAY_THRESH: u16 = 11;
pub const XFRMA_ETIMER_THRESH: u16 = 12;
pub const XFRMA_SRCADDR: u16 = 13;
pub const XFRMA_COADDR: u16 = 14;
pub const XFRMA_LASTUSED: u16 = 15;
pub const XFRMA_POLICY_TYPE: u16 = 16;
pub const XFRMA_MIGRATE: u16 = 17;
pub const XFRMA_ALG_AEAD: u16 = 18;
pub const XFRMA_KMADDRESS: u16 = 19;
pub const XFRMA_ALG_AUTH_TRUNC: u16 = 20;
pub const XFRMA_MARK: u16 = 21;
pub const XFRMA_TFCPAD: u16 = 22;
pub const XFRMA_REPLAY_ESN_VAL: u16 = 23;
pub const XFRMA_SA_EXTRA_FLAGS: u16 = 24;
pub const XFRMA_PROTO: u16 = 25;
pub const XFRMA_ADDRESS_FILTER: u16 = 26;
pub const XFRMA_PAD: u16 = 27;
pub const XFRMA_OFFLOAD_DEV: u16 = 28;
pub const XFRMA_SET_MARK: u16 = 29;
pub const XFRMA_SET_MARK_MASK: u16 = 30;
pub const XFRMA_IF_ID: u16 = 31;
}
pub mod nft_ct_keys {
pub const NFT_CT_STATE: u32 = 0;
pub const NFT_CT_DIRECTION: u32 = 1;
pub const NFT_CT_STATUS: u32 = 2;
pub const NFT_CT_MARK: u32 = 3;
pub const NFT_CT_SECMARK: u32 = 4;
pub const NFT_CT_EXPIRATION: u32 = 5;
pub const NFT_CT_HELPER: u32 = 6;
pub const NFT_CT_L3PROTOCOL: u32 = 7;
pub const NFT_CT_SRC: u32 = 8;
pub const NFT_CT_DST: u32 = 9;
pub const NFT_CT_PROTOCOL: u32 = 10;
pub const NFT_CT_PROTO_SRC: u32 = 11;
pub const NFT_CT_PROTO_DST: u32 = 12;
pub const NFT_CT_LABELS: u32 = 13;
pub const NFT_CT_PKTS: u32 = 14;
pub const NFT_CT_BYTES: u32 = 15;
pub const NFT_CT_AVGPKT: u32 = 16;
pub const NFT_CT_ZONE: u32 = 17;
pub const NFT_CT_EVENTMASK: u32 = 18;
pub const NFT_CT_SRC_IP: u32 = 19;
pub const NFT_CT_DST_IP: u32 = 20;
pub const NFT_CT_SRC_IP6: u32 = 21;
pub const NFT_CT_DST_IP6: u32 = 22;
pub const NFT_CT_ID: u32 = 23;
}
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));
}
#[test]
fn plan_222_1_xfrm_msg_types_match_kernel_uapi() {
assert_eq!(xfrm_msg_type::XFRM_MSG_NEWSA, 16);
assert_eq!(xfrm_msg_type::XFRM_MSG_DELSA, 17);
assert_eq!(xfrm_msg_type::XFRM_MSG_GETSA, 18);
assert_eq!(xfrm_msg_type::XFRM_MSG_NEWPOLICY, 19);
assert_eq!(xfrm_msg_type::XFRM_MSG_DELPOLICY, 20);
assert_eq!(xfrm_msg_type::XFRM_MSG_GETPOLICY, 21);
assert_eq!(xfrm_msg_type::XFRM_MSG_UPDPOLICY, 25);
assert_eq!(xfrm_msg_type::XFRM_MSG_UPDSA, 26);
assert_eq!(
xfrm_msg_type::XFRM_MSG_FLUSHSA,
28,
"Plan 222.1: FLUSHSA was hardcoded to 25 (= UPDPOLICY) pre-Plan-221"
);
assert_eq!(
xfrm_msg_type::XFRM_MSG_FLUSHPOLICY,
29,
"Plan 222.1: FLUSHPOLICY was hardcoded to 28 (= FLUSHSA) pre-Plan-221 — \
flush_policy() was SILENTLY flushing all SAs"
);
}
#[test]
fn plan_222_1_xfrm_attr_ids_match_kernel_uapi() {
assert_eq!(xfrm_attr::XFRMA_LTIME_VAL, 9);
assert_eq!(
xfrm_attr::XFRMA_SRCADDR,
13,
"Plan 222.1: XFRMA_SRCADDR was hardcoded to 9 (= LTIME_VAL) pre-Plan-221"
);
assert_eq!(xfrm_attr::XFRMA_ADDRESS_FILTER, 26);
assert_eq!(
xfrm_attr::XFRMA_OFFLOAD_DEV,
28,
"Plan 222.1: XFRMA_OFFLOAD_DEV was hardcoded to 26 (= ADDRESS_FILTER) pre-Plan-221"
);
assert_eq!(xfrm_attr::XFRMA_IF_ID, 31);
}
#[test]
fn plan_222_1_nft_ct_keys_match_kernel_uapi() {
use crate::netlink::nftables::types::CtKey;
assert_eq!(CtKey::State as u32, nft_ct_keys::NFT_CT_STATE);
assert_eq!(CtKey::Direction as u32, nft_ct_keys::NFT_CT_DIRECTION);
assert_eq!(CtKey::Status as u32, nft_ct_keys::NFT_CT_STATUS);
assert_eq!(CtKey::Mark as u32, nft_ct_keys::NFT_CT_MARK);
assert_eq!(CtKey::Secmark as u32, nft_ct_keys::NFT_CT_SECMARK);
assert_eq!(
CtKey::Expiration as u32,
nft_ct_keys::NFT_CT_EXPIRATION,
"Plan 222.1: CtKey::Expiration was hardcoded to 7 (= NFT_CT_L3PROTOCOL) \
pre-Plan-221 — every Expr::Ct{{key:Expiration}} read the L3 protocol byte"
);
assert_eq!(CtKey::Helper as u32, nft_ct_keys::NFT_CT_HELPER);
assert_eq!(CtKey::L3Protocol as u32, nft_ct_keys::NFT_CT_L3PROTOCOL);
}
}