aboutsummaryrefslogtreecommitdiff
path: root/nftnl/src/lib.rs
blob: 69cb1c86506c9a5ca524a2bfe2a94ea1356818b3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright 2018 Amagicom AB.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Safe abstraction for [`libnftnl`]. Provides low-level userspace access to the in-kernel
//! nf_tables subsystem. See [`nftnl-sys`] for the low level FFI bindings to the C library.
//!
//! Can be used to create and remove tables, chains, sets and rules from the nftables firewall,
//! the successor to iptables.
//!
//! # Selecting version of `libnftnl`
//!
//! See the documentation for the corresponding sys crate for details: [`nftnl-sys`]
//! This crate has the same features as the sys crate, and selecting version works the same.
//!
//! [`libnftnl`]: https://netfilter.org/projects/libnftnl/
//! [`nftnl-sys`]: https://crates.io/crates/nftnl-sys

pub extern crate nftnl_sys;

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate error_chain;
extern crate libc;
#[macro_use]
extern crate log;

use nftnl_sys::libc::c_void;

pub use error_chain::ChainedError;
error_chain! {
    errors {
        AllocationError { description("Unable to allocate memory") }
        BatchIsFull { description("Not enough room in the batch") }
        NetlinkError { description("Error while communicating with netlink") }
    }
}

mod batch;
pub use batch::{batch_is_supported, default_batch_page_size, Batch, FinalizedBatch};

pub mod expr;

mod table;
pub use table::Table;

mod chain;
pub use chain::{Chain, Hook, Policy, Priority};

mod rule;
pub use rule::Rule;

pub mod set;

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum MsgType {
    Add,
    Del,
}

#[derive(Debug, Copy, Clone)]
#[repr(u16)]
pub enum ProtoFamily {
    Unspec = libc::NFPROTO_UNSPEC as u16,
    Inet = libc::NFPROTO_INET as u16,
    Ipv4 = libc::NFPROTO_IPV4 as u16,
    Arp = libc::NFPROTO_ARP as u16,
    NetDev = libc::NFPROTO_NETDEV as u16,
    Bridge = libc::NFPROTO_BRIDGE as u16,
    Ipv6 = libc::NFPROTO_IPV6 as u16,
    DecNet = libc::NFPROTO_DECNET as u16,
}

/// Trait for all types in this crate that can serialize to a Netlink message.
///
/// # Unsafe
///
/// This trait is unsafe to implement because it must never serialize to anything larger than the
/// largest possible netlink message. Internally the `nft_nlmsg_maxsize()` function is used to make
/// sure the `buf` pointer passed to `write` always has room for the largest possible Netlink
/// message.
pub unsafe trait NlMsg {
    /// Serializes the Netlink message to the buffer at `buf`. `buf` must have space for at least
    /// `nft_nlmsg_maxsize()` bytes. This is not checked by the compiler, which is why this method
    /// is unsafe.
    unsafe fn write(&self, buf: *mut c_void, seq: u32, msg_type: MsgType);
}

/// The largest nf_tables netlink message is the set element message, which
/// contains the NFTA_SET_ELEM_LIST_ELEMENTS attribute. This attribute is
/// a nest that describes the set elements. Given that the netlink attribute
/// length (nla_len) is 16 bits, the largest message is a bit larger than
/// 64 KBytes.
pub fn nft_nlmsg_maxsize() -> u32 {
    u32::from(::std::u16::MAX) + unsafe { libc::sysconf(libc::_SC_PAGESIZE) } as u32
}