@push.rocks/smartnftables 4.3.1 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +17 -0
- package/dist_rust/smartnftables_linux_amd64_musl +0 -0
- package/dist_rust/smartnftables_linux_amd64_musl.tsrust-build.json +5 -5
- package/dist_rust/smartnftables_linux_arm64_musl +0 -0
- package/dist_rust/smartnftables_linux_arm64_musl.tsrust-build.json +5 -5
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/managed.egress.types.d.ts +25 -4
- package/package.json +4 -4
- package/readme.md +89 -2
- package/rust/src/egress.compile.rs +105 -38
- package/rust/src/egress.hostgrant.rs +74 -34
- package/rust/src/egress.keys.rs +383 -52
- package/rust/src/egress.leased.rs +71 -42
- package/rust/src/egress.poolguard.rs +72 -0
- package/rust/src/egress.private.rs +32 -37
- package/rust/src/egress.published.rs +74 -47
- package/rust/src/egress.router.rs +1 -1
- package/rust/src/egress.rs +65 -1
- package/rust/src/egress.workloadgrant.rs +30 -28
- package/rust/src/egress_hostgrant_tests.rs +12 -0
- package/rust/src/egress_keys_tests.rs +150 -0
- package/rust/src/egress_poolguardpublished_tests.rs +418 -0
- package/rust/src/egress_tests.rs +47 -4
- package/rust/src/owner.rs +96 -28
- package/rust/src/owner_listing_tests.rs +634 -0
- package/rust/src/owner_tests.rs +3 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/managed.egress.types.ts +26 -4
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
//! variable interface (index and name), the packet and conntrack protocols, the
|
|
5
5
|
//! live tuple and the originally tracked tuple. An element is one grant with its
|
|
6
6
|
//! live tuple equal to its original tuple, so translated flows never match.
|
|
7
|
+
use super::keys::{
|
|
8
|
+
Field, Loads, CT_ORIGINAL_DADDR, CT_ORIGINAL_DPORT, CT_ORIGINAL_SADDR, CT_PROTOCOL, IP_DADDR,
|
|
9
|
+
IP_SADDR, L4PROTO, OIF, OIFNAME, TH_DPORT,
|
|
10
|
+
};
|
|
7
11
|
use super::*;
|
|
8
12
|
|
|
9
13
|
/// Every exact host-origin flow of the scope, keyed on its full tuple.
|
|
@@ -11,6 +15,42 @@ pub(super) const TUPLE_SET: &str = "host_grant";
|
|
|
11
15
|
/// Router raw ingress runs before conntrack: exact arriving tuples only.
|
|
12
16
|
pub(super) const ARRIVAL_SET: &str = "host_grant_arrival";
|
|
13
17
|
|
|
18
|
+
/// The tuple key of a link-independent scope: both protocols, the live tuple
|
|
19
|
+
/// and the originally tracked tuple, as the original direction loads them.
|
|
20
|
+
pub(super) const TUPLE: [Field; 8] = [
|
|
21
|
+
L4PROTO,
|
|
22
|
+
CT_PROTOCOL,
|
|
23
|
+
IP_SADDR,
|
|
24
|
+
IP_DADDR,
|
|
25
|
+
TH_DPORT,
|
|
26
|
+
CT_ORIGINAL_SADDR,
|
|
27
|
+
CT_ORIGINAL_DADDR,
|
|
28
|
+
CT_ORIGINAL_DPORT,
|
|
29
|
+
];
|
|
30
|
+
/// The tuple key behind the variable interface: its index and name first.
|
|
31
|
+
const LINKED_TUPLE: [Field; 10] = [
|
|
32
|
+
OIF,
|
|
33
|
+
OIFNAME,
|
|
34
|
+
L4PROTO,
|
|
35
|
+
CT_PROTOCOL,
|
|
36
|
+
IP_SADDR,
|
|
37
|
+
IP_DADDR,
|
|
38
|
+
TH_DPORT,
|
|
39
|
+
CT_ORIGINAL_SADDR,
|
|
40
|
+
CT_ORIGINAL_DADDR,
|
|
41
|
+
CT_ORIGINAL_DPORT,
|
|
42
|
+
];
|
|
43
|
+
/// The exact arriving tuple: protocol, addresses and port.
|
|
44
|
+
const ARRIVAL: [Field; 4] = [L4PROTO, IP_SADDR, IP_DADDR, TH_DPORT];
|
|
45
|
+
|
|
46
|
+
fn tuple(linked: bool) -> &'static [Field] {
|
|
47
|
+
if linked {
|
|
48
|
+
&LINKED_TUPLE
|
|
49
|
+
} else {
|
|
50
|
+
&TUPLE
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
14
54
|
/// Register numbers as Linux dumps them: 16-byte aligned registers use the
|
|
15
55
|
/// legacy NFT_REG_1..4 names, every other 4-byte register NFT_REG32_xx.
|
|
16
56
|
pub(super) fn register(index: u32) -> u32 {
|
|
@@ -38,10 +78,11 @@ pub(super) fn payload_to(base: u32, offset: u32, length: u32, index: u32) -> Att
|
|
|
38
78
|
index,
|
|
39
79
|
)
|
|
40
80
|
}
|
|
41
|
-
|
|
81
|
+
/// A conntrack key of the original (0) or reply (1) tuple, or of neither.
|
|
82
|
+
pub(super) fn ct_to(key: u32, direction: Option<u8>, index: u32) -> Attr {
|
|
42
83
|
let mut data = vec![Attr::u32(2, key)];
|
|
43
|
-
if
|
|
44
|
-
data.push(Attr::bytes(3, vec![
|
|
84
|
+
if let Some(direction) = direction {
|
|
85
|
+
data.push(Attr::bytes(3, vec![direction]));
|
|
45
86
|
}
|
|
46
87
|
store("ct", data, index)
|
|
47
88
|
}
|
|
@@ -64,26 +105,22 @@ fn word(bytes: &[u8]) -> Vec<u8> {
|
|
|
64
105
|
/// Key loads for one direction, then the lookup in `set`. `linked` adds the
|
|
65
106
|
/// variable interface: the outgoing interface of the original direction, the
|
|
66
107
|
/// incoming interface of the reply.
|
|
67
|
-
pub(super) fn tuple_lookup(set: &str, linked: bool, reply: bool) -> Vec<Attr
|
|
68
|
-
let mut
|
|
69
|
-
let mut index = 4;
|
|
108
|
+
pub(super) fn tuple_lookup(set: &str, linked: bool, reply: bool) -> Result<Vec<Attr>> {
|
|
109
|
+
let mut loads = Loads::new();
|
|
70
110
|
if linked {
|
|
71
|
-
|
|
72
|
-
result.push(meta_to(if reply { 6 } else { 7 }, index + 1));
|
|
73
|
-
index += 5;
|
|
111
|
+
loads.link(reply);
|
|
74
112
|
}
|
|
75
|
-
result.push(meta_to(16, index));
|
|
76
|
-
result.push(ct_to(10, false, index + 1));
|
|
77
113
|
// The grant's source and destination are the packet's own addresses in the
|
|
78
114
|
// original direction and swapped on the reply; the port is the workload's.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
115
|
+
loads
|
|
116
|
+
.protocols()
|
|
117
|
+
.address(!reply)
|
|
118
|
+
.address(reply)
|
|
119
|
+
.port(reply)
|
|
120
|
+
.original_address(true)
|
|
121
|
+
.original_address(false)
|
|
122
|
+
.original_port(false);
|
|
123
|
+
loads.lookup(set, tuple(linked))
|
|
87
124
|
}
|
|
88
125
|
pub(super) fn tuple_key(grant: &HostGrant, link: Option<&LocalLink>) -> Result<Vec<u8>> {
|
|
89
126
|
let protocol = word(&[protocol(&grant.protocol)]);
|
|
@@ -120,11 +157,15 @@ pub(super) fn tuple_set<'s>(
|
|
|
120
157
|
link: impl Fn(&HostGrant) -> Result<Option<&'s LocalLink>>,
|
|
121
158
|
) -> Result<()> {
|
|
122
159
|
let mut keys = Vec::new();
|
|
160
|
+
let mut linked = false;
|
|
123
161
|
for grant in grants {
|
|
124
|
-
|
|
162
|
+
let link = link(grant)?;
|
|
163
|
+
linked = link.is_some();
|
|
164
|
+
keys.push(tuple_key(grant, link)?);
|
|
125
165
|
}
|
|
126
|
-
|
|
127
|
-
|
|
166
|
+
// Every element has the declared key's length, so a scope never mixes them.
|
|
167
|
+
require(!keys.is_empty())?;
|
|
168
|
+
program.exact_set(TUPLE_SET, 1, tuple(linked), None)?;
|
|
128
169
|
program.elements(TUPLE_SET, keys)
|
|
129
170
|
}
|
|
130
171
|
pub(super) fn arrival_set(program: &mut Program<'_>, grants: &[HostGrant]) -> Result<()> {
|
|
@@ -136,18 +177,17 @@ pub(super) fn arrival_set(program: &mut Program<'_>, grants: &[HostGrant]) -> Re
|
|
|
136
177
|
key.extend(word(&grant.destination_port.to_be_bytes()));
|
|
137
178
|
keys.push(key);
|
|
138
179
|
}
|
|
139
|
-
program.
|
|
180
|
+
program.exact_set(ARRIVAL_SET, 2, &ARRIVAL, None)?;
|
|
140
181
|
program.elements(ARRIVAL_SET, keys)
|
|
141
182
|
}
|
|
142
183
|
/// Exact arriving tuple, before conntrack: protocol, addresses and port.
|
|
143
|
-
pub(super) fn arrival_lookup() -> Vec<Attr
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
lookup(ARRIVAL_SET)
|
|
150
|
-
]
|
|
184
|
+
pub(super) fn arrival_lookup() -> Result<Vec<Attr>> {
|
|
185
|
+
Loads::new()
|
|
186
|
+
.protocol()
|
|
187
|
+
.address(true)
|
|
188
|
+
.address(false)
|
|
189
|
+
.port(false)
|
|
190
|
+
.lookup(ARRIVAL_SET, &ARRIVAL)
|
|
151
191
|
}
|
|
152
192
|
|
|
153
193
|
/// Four admissions whatever the number of grants: the ESTABLISHED original
|
|
@@ -170,7 +210,7 @@ pub(super) fn admissions(
|
|
|
170
210
|
result
|
|
171
211
|
};
|
|
172
212
|
let mut established = envelope(false, 2);
|
|
173
|
-
established.extend(tuple_lookup(TUPLE_SET, linked, false));
|
|
213
|
+
established.extend(tuple_lookup(TUPLE_SET, linked, false)?);
|
|
174
214
|
program.end(chains[0], established, 1)?;
|
|
175
215
|
for transport in ["udp", "tcp"] {
|
|
176
216
|
let mut opening = envelope(false, 8);
|
|
@@ -178,10 +218,10 @@ pub(super) fn admissions(
|
|
|
178
218
|
if transport == "tcp" {
|
|
179
219
|
opening.extend(opening_tcp());
|
|
180
220
|
}
|
|
181
|
-
opening.extend(tuple_lookup(TUPLE_SET, linked, false));
|
|
221
|
+
opening.extend(tuple_lookup(TUPLE_SET, linked, false)?);
|
|
182
222
|
program.end(chains[0], opening, 1)?;
|
|
183
223
|
}
|
|
184
224
|
let mut reply = envelope(true, 2);
|
|
185
|
-
reply.extend(tuple_lookup(TUPLE_SET, linked, true));
|
|
225
|
+
reply.extend(tuple_lookup(TUPLE_SET, linked, true)?);
|
|
186
226
|
program.end(chains[1], reply, 1)
|
|
187
227
|
}
|