Skip to content

Commit 3fd1242

Browse files
committed
refactor: use enums for subsystem and message types
This refactors the crate to use type-safe enums for netfilter subsystems and message types, for a safer and more idiomatic API. - Introduces a `Subsystem` enum to replace raw `u8` identifiers for `NfLog` and `Conntrack` subsystems. - Introduces `NfLogMessageType` and `ConntrackMessageType` enums to provide type safety for messages within each subsystem. - Makes the top-level `NetfilterMessage::message_type()` function private to guide users towards the safer pattern of matching on `NetfilterMessageInner`. - Updates the internal parsing logic in `buffer.rs` to use the new `Subsystem` enum. Signed-off-by: Shivang K Raghuvanshi <[email protected]>
1 parent 627221a commit 3fd1242

File tree

10 files changed

+166
-82
lines changed

10 files changed

+166
-82
lines changed

examples/nflog.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ use netlink_packet_netfilter::{
1717
config::{ConfigCmd, ConfigFlags, ConfigMode, Timeout},
1818
packet::PacketNla,
1919
},
20-
NfLogMessage,
20+
ULogMessage,
2121
},
2222
NetfilterMessage, NetfilterMessageInner,
2323
};
2424
use netlink_sys::{constants::NETLINK_NETFILTER, Socket};
2525

2626
fn get_packet_nlas(message: &NetlinkMessage<NetfilterMessage>) -> &[PacketNla] {
2727
if let NetlinkPayload::InnerMessage(NetfilterMessage {
28-
inner: NetfilterMessageInner::NfLog(NfLogMessage::Packet(nlas)),
28+
inner: NetfilterMessageInner::ULog(ULogMessage::Packet(nlas)),
2929
..
3030
}) = &message.payload
3131
{

src/buffer.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
use crate::{
44
conntrack::ConntrackMessage,
55
message::{
6-
NetfilterHeader, NetfilterMessage, NetfilterMessageInner,
6+
NetfilterHeader, NetfilterMessage, NetfilterMessageInner, Subsystem,
77
NETFILTER_HEADER_LEN,
88
},
9-
nflog::NfLogMessage,
9+
nflog::ULogMessage,
1010
};
1111
use netlink_packet_core::{
1212
buffer, fields, DecodeError, DefaultNla, ErrorContext, NlaBuffer,
@@ -53,17 +53,17 @@ impl<'a, T: AsRef<[u8]> + ?Sized>
5353
.context("failed to parse netfilter header")?;
5454
let subsys = (message_type >> 8) as u8;
5555
let message_type = message_type as u8;
56-
let inner = match subsys {
57-
NfLogMessage::SUBSYS => NetfilterMessageInner::NfLog(
58-
NfLogMessage::parse_with_param(buf, message_type)
56+
let inner = match Subsystem::from(subsys) {
57+
Subsystem::ULog => NetfilterMessageInner::ULog(
58+
ULogMessage::parse_with_param(buf, message_type)
5959
.context("failed to parse nflog payload")?,
6060
),
61-
ConntrackMessage::SUBSYS => NetfilterMessageInner::Conntrack(
61+
Subsystem::Conntrack => NetfilterMessageInner::Conntrack(
6262
ConntrackMessage::parse_with_param(buf, message_type)
6363
.context("failed to parse conntrack payload")?,
6464
),
65-
_ => NetfilterMessageInner::Other {
66-
subsys,
65+
subsys_enum @ Subsystem::Other(_) => NetfilterMessageInner::Other {
66+
subsys: subsys_enum,
6767
message_type,
6868
attributes: buf.default_nlas()?,
6969
},

src/conntrack/message.rs

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
// SPDX-License-Identifier: MIT
22

33
use crate::{
4-
buffer::NetfilterBuffer,
5-
conntrack::attributes::ConntrackAttribute,
6-
constants::{IPCTNL_MSG_CT_GET, NFNL_SUBSYS_CTNETLINK},
4+
buffer::NetfilterBuffer, conntrack::attributes::ConntrackAttribute,
75
};
86
use netlink_packet_core::{
97
DecodeError, DefaultNla, Emitable, Parseable, ParseableParametrized,
@@ -19,13 +17,40 @@ pub enum ConntrackMessage {
1917
},
2018
}
2119

22-
impl ConntrackMessage {
23-
pub(crate) const SUBSYS: u8 = NFNL_SUBSYS_CTNETLINK;
20+
const IPCTNL_MSG_CT_GET: u8 = 1;
21+
22+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23+
#[non_exhaustive]
24+
pub enum ConntrackMessageType {
25+
Get,
26+
Other(u8),
27+
}
28+
29+
impl From<u8> for ConntrackMessageType {
30+
fn from(value: u8) -> Self {
31+
match value {
32+
IPCTNL_MSG_CT_GET => Self::Get,
33+
v => Self::Other(v),
34+
}
35+
}
36+
}
2437

25-
pub fn message_type(&self) -> u8 {
38+
impl From<ConntrackMessageType> for u8 {
39+
fn from(value: ConntrackMessageType) -> Self {
40+
match value {
41+
ConntrackMessageType::Get => IPCTNL_MSG_CT_GET,
42+
ConntrackMessageType::Other(v) => v,
43+
}
44+
}
45+
}
46+
47+
impl ConntrackMessage {
48+
pub fn message_type(&self) -> ConntrackMessageType {
2649
match self {
27-
ConntrackMessage::Get(_) => IPCTNL_MSG_CT_GET,
28-
ConntrackMessage::Other { message_type, .. } => *message_type,
50+
ConntrackMessage::Get(_) => ConntrackMessageType::Get,
51+
ConntrackMessage::Other { message_type, .. } => {
52+
(*message_type).into()
53+
}
2954
}
3055
}
3156
}
@@ -61,17 +86,19 @@ impl<'a, T: AsRef<[u8]> + ?Sized>
6186
buf: &NetfilterBuffer<&'a T>,
6287
message_type: u8,
6388
) -> Result<Self, DecodeError> {
64-
Ok(match message_type {
65-
IPCTNL_MSG_CT_GET => {
89+
Ok(match ConntrackMessageType::from(message_type) {
90+
ConntrackMessageType::Get => {
6691
let attributes = buf.parse_all_nlas(|nla_buf| {
6792
ConntrackAttribute::parse(&nla_buf)
6893
})?;
6994
ConntrackMessage::Get(attributes)
7095
}
71-
_ => ConntrackMessage::Other {
72-
message_type,
73-
attributes: buf.default_nlas()?,
74-
},
96+
ConntrackMessageType::Other(message_type) => {
97+
ConntrackMessage::Other {
98+
message_type,
99+
attributes: buf.default_nlas()?,
100+
}
101+
}
75102
})
76103
}
77104
}

src/conntrack/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22

33
mod message;
4-
pub use message::ConntrackMessage;
4+
pub use message::{ConntrackMessage, ConntrackMessageType};
55
mod attributes;
66
pub use attributes::{
77
ConntrackAttribute, IPTuple, ProtoInfo, ProtoInfoTCP, ProtoTuple, Protocol,

src/constants.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,8 @@ pub const AF_ALG: u8 = libc::AF_ALG as u8;
4343
pub const NFNETLINK_V0: u8 = libc::NFNETLINK_V0 as u8;
4444

4545
pub const NFNL_SUBSYS_NONE: u8 = libc::NFNL_SUBSYS_NONE as u8;
46-
pub const NFNL_SUBSYS_CTNETLINK: u8 = libc::NFNL_SUBSYS_CTNETLINK as u8;
4746
pub const NFNL_SUBSYS_CTNETLINK_EXP: u8 = libc::NFNL_SUBSYS_CTNETLINK_EXP as u8;
4847
pub const NFNL_SUBSYS_QUEUE: u8 = libc::NFNL_SUBSYS_QUEUE as u8;
49-
pub const NFNL_SUBSYS_ULOG: u8 = libc::NFNL_SUBSYS_ULOG as u8;
5048
pub const NFNL_SUBSYS_OSF: u8 = libc::NFNL_SUBSYS_OSF as u8;
5149
pub const NFNL_SUBSYS_IPSET: u8 = libc::NFNL_SUBSYS_IPSET as u8;
5250
pub const NFNL_SUBSYS_ACCT: u8 = libc::NFNL_SUBSYS_ACCT as u8;
@@ -83,8 +81,3 @@ pub const NFULA_HWHEADER: u16 = libc::NFULA_HWHEADER as u16;
8381
pub const NFULA_HWLEN: u16 = libc::NFULA_HWLEN as u16;
8482
pub const NFULA_CT: u16 = libc::NFULA_CT as u16;
8583
pub const NFULA_CT_INFO: u16 = libc::NFULA_CT_INFO as u16;
86-
87-
pub const NFULNL_MSG_CONFIG: u8 = libc::NFULNL_MSG_CONFIG as u8;
88-
pub const NFULNL_MSG_PACKET: u8 = libc::NFULNL_MSG_PACKET as u8;
89-
90-
pub(crate) const IPCTNL_MSG_CT_GET: u8 = 1;

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
pub(crate) mod buffer;
44
pub mod constants;
55
mod message;
6-
pub use message::{NetfilterHeader, NetfilterMessage, NetfilterMessageInner};
6+
pub use message::{
7+
NetfilterHeader, NetfilterMessage, NetfilterMessageInner, Subsystem,
8+
};
79
pub mod conntrack;
810
pub mod nflog;
911
#[cfg(test)]

src/message.rs

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use netlink_packet_core::{
77
};
88

99
use crate::{
10-
buffer::NetfilterBuffer, conntrack::ConntrackMessage, nflog::NfLogMessage,
10+
buffer::NetfilterBuffer, conntrack::ConntrackMessage, nflog::ULogMessage,
1111
};
1212

1313
pub(crate) const NETFILTER_HEADER_LEN: usize = 4;
@@ -60,21 +60,53 @@ impl<T: AsRef<[u8]>> Parseable<NetfilterHeaderBuffer<T>> for NetfilterHeader {
6060
}
6161
}
6262

63+
// Defined in Linux kernel: include/uapi/linux/netfilter/nfnetlink.h
64+
pub const NFNL_SUBSYS_CTNETLINK: u8 = 1;
65+
pub const NFNL_SUBSYS_ULOG: u8 = 4;
66+
67+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
68+
#[non_exhaustive]
69+
pub enum Subsystem {
70+
ULog,
71+
Conntrack,
72+
Other(u8),
73+
}
74+
75+
impl From<u8> for Subsystem {
76+
fn from(value: u8) -> Self {
77+
match value {
78+
NFNL_SUBSYS_ULOG => Self::ULog,
79+
NFNL_SUBSYS_CTNETLINK => Self::Conntrack,
80+
v => Self::Other(v),
81+
}
82+
}
83+
}
84+
85+
impl From<Subsystem> for u8 {
86+
fn from(value: Subsystem) -> Self {
87+
match value {
88+
Subsystem::ULog => NFNL_SUBSYS_ULOG,
89+
Subsystem::Conntrack => NFNL_SUBSYS_CTNETLINK,
90+
Subsystem::Other(v) => v,
91+
}
92+
}
93+
}
94+
6395
#[derive(Debug, PartialEq, Eq, Clone)]
6496
#[non_exhaustive]
6597
pub enum NetfilterMessageInner {
66-
NfLog(NfLogMessage),
98+
ULog(ULogMessage),
6799
Conntrack(ConntrackMessage),
68100
Other {
69-
subsys: u8,
101+
subsys: Subsystem,
70102
message_type: u8,
71103
attributes: Vec<DefaultNla>,
72104
},
73105
}
74106

75-
impl From<NfLogMessage> for NetfilterMessageInner {
76-
fn from(message: NfLogMessage) -> Self {
77-
Self::NfLog(message)
107+
impl From<ULogMessage> for NetfilterMessageInner {
108+
fn from(message: ULogMessage) -> Self {
109+
Self::ULog(message)
78110
}
79111
}
80112
impl From<ConntrackMessage> for NetfilterMessageInner {
@@ -86,7 +118,7 @@ impl From<ConntrackMessage> for NetfilterMessageInner {
86118
impl Emitable for NetfilterMessageInner {
87119
fn buffer_len(&self) -> usize {
88120
match self {
89-
NetfilterMessageInner::NfLog(message) => message.buffer_len(),
121+
NetfilterMessageInner::ULog(message) => message.buffer_len(),
90122
NetfilterMessageInner::Conntrack(message) => message.buffer_len(),
91123
NetfilterMessageInner::Other { attributes, .. } => {
92124
attributes.as_slice().buffer_len()
@@ -96,7 +128,7 @@ impl Emitable for NetfilterMessageInner {
96128

97129
fn emit(&self, buffer: &mut [u8]) {
98130
match self {
99-
NetfilterMessageInner::NfLog(message) => message.emit(buffer),
131+
NetfilterMessageInner::ULog(message) => message.emit(buffer),
100132
NetfilterMessageInner::Conntrack(message) => message.emit(buffer),
101133
NetfilterMessageInner::Other { attributes, .. } => {
102134
attributes.as_slice().emit(buffer)
@@ -123,19 +155,21 @@ impl NetfilterMessage {
123155
}
124156
}
125157

126-
pub fn subsys(&self) -> u8 {
158+
pub fn subsys(&self) -> Subsystem {
127159
match self.inner {
128-
NetfilterMessageInner::NfLog(_) => NfLogMessage::SUBSYS,
129-
NetfilterMessageInner::Conntrack(_) => ConntrackMessage::SUBSYS,
160+
NetfilterMessageInner::ULog(_) => Subsystem::ULog,
161+
NetfilterMessageInner::Conntrack(_) => Subsystem::Conntrack,
130162
NetfilterMessageInner::Other { subsys, .. } => subsys,
131163
}
132164
}
133165

134-
pub fn message_type(&self) -> u8 {
166+
fn message_type(&self) -> u8 {
135167
match self.inner {
136-
NetfilterMessageInner::NfLog(ref message) => message.message_type(),
168+
NetfilterMessageInner::ULog(ref message) => {
169+
message.message_type().into()
170+
}
137171
NetfilterMessageInner::Conntrack(ref message) => {
138-
message.message_type()
172+
message.message_type().into()
139173
}
140174
NetfilterMessageInner::Other { message_type, .. } => message_type,
141175
}
@@ -155,7 +189,7 @@ impl Emitable for NetfilterMessage {
155189

156190
impl NetlinkSerializable for NetfilterMessage {
157191
fn message_type(&self) -> u16 {
158-
((self.subsys() as u16) << 8) | self.message_type() as u16
192+
((u8::from(self.subsys()) as u16) << 8) | self.message_type() as u16
159193
}
160194

161195
fn buffer_len(&self) -> usize {

0 commit comments

Comments
 (0)