1#![doc = "Foo\\-over\\-UDP\\.\n"]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &str = "fou";
17pub const PROTONAME_CSTR: &CStr = c"fou";
18#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
19#[derive(Debug, Clone, Copy)]
20pub enum EncapType {
21 Unspec = 0,
22 Direct = 1,
23 Gue = 2,
24}
25impl EncapType {
26 pub fn from_value(value: u64) -> Option<Self> {
27 Some(match value {
28 0 => Self::Unspec,
29 1 => Self::Direct,
30 2 => Self::Gue,
31 _ => return None,
32 })
33 }
34}
35#[derive(Clone)]
36pub enum Fou<'a> {
37 Port(u16),
38 Af(u8),
39 Ipproto(u8),
40 Type(u8),
41 RemcsumNopartial(()),
42 LocalV4(u32),
43 LocalV6(&'a [u8]),
44 PeerV4(u32),
45 PeerV6(&'a [u8]),
46 PeerPort(u16),
47 Ifindex(i32),
48}
49impl<'a> IterableFou<'a> {
50 pub fn get_port(&self) -> Result<u16, ErrorContext> {
51 let mut iter = self.clone();
52 iter.pos = 0;
53 for attr in iter {
54 if let Fou::Port(val) = attr? {
55 return Ok(val);
56 }
57 }
58 Err(ErrorContext::new_missing(
59 "Fou",
60 "Port",
61 self.orig_loc,
62 self.buf.as_ptr() as usize,
63 ))
64 }
65 pub fn get_af(&self) -> Result<u8, ErrorContext> {
66 let mut iter = self.clone();
67 iter.pos = 0;
68 for attr in iter {
69 if let Fou::Af(val) = attr? {
70 return Ok(val);
71 }
72 }
73 Err(ErrorContext::new_missing(
74 "Fou",
75 "Af",
76 self.orig_loc,
77 self.buf.as_ptr() as usize,
78 ))
79 }
80 pub fn get_ipproto(&self) -> Result<u8, ErrorContext> {
81 let mut iter = self.clone();
82 iter.pos = 0;
83 for attr in iter {
84 if let Fou::Ipproto(val) = attr? {
85 return Ok(val);
86 }
87 }
88 Err(ErrorContext::new_missing(
89 "Fou",
90 "Ipproto",
91 self.orig_loc,
92 self.buf.as_ptr() as usize,
93 ))
94 }
95 pub fn get_type(&self) -> Result<u8, ErrorContext> {
96 let mut iter = self.clone();
97 iter.pos = 0;
98 for attr in iter {
99 if let Fou::Type(val) = attr? {
100 return Ok(val);
101 }
102 }
103 Err(ErrorContext::new_missing(
104 "Fou",
105 "Type",
106 self.orig_loc,
107 self.buf.as_ptr() as usize,
108 ))
109 }
110 pub fn get_remcsum_nopartial(&self) -> Result<(), ErrorContext> {
111 let mut iter = self.clone();
112 iter.pos = 0;
113 for attr in iter {
114 if let Fou::RemcsumNopartial(val) = attr? {
115 return Ok(val);
116 }
117 }
118 Err(ErrorContext::new_missing(
119 "Fou",
120 "RemcsumNopartial",
121 self.orig_loc,
122 self.buf.as_ptr() as usize,
123 ))
124 }
125 pub fn get_local_v4(&self) -> Result<u32, ErrorContext> {
126 let mut iter = self.clone();
127 iter.pos = 0;
128 for attr in iter {
129 if let Fou::LocalV4(val) = attr? {
130 return Ok(val);
131 }
132 }
133 Err(ErrorContext::new_missing(
134 "Fou",
135 "LocalV4",
136 self.orig_loc,
137 self.buf.as_ptr() as usize,
138 ))
139 }
140 pub fn get_local_v6(&self) -> Result<&'a [u8], ErrorContext> {
141 let mut iter = self.clone();
142 iter.pos = 0;
143 for attr in iter {
144 if let Fou::LocalV6(val) = attr? {
145 return Ok(val);
146 }
147 }
148 Err(ErrorContext::new_missing(
149 "Fou",
150 "LocalV6",
151 self.orig_loc,
152 self.buf.as_ptr() as usize,
153 ))
154 }
155 pub fn get_peer_v4(&self) -> Result<u32, ErrorContext> {
156 let mut iter = self.clone();
157 iter.pos = 0;
158 for attr in iter {
159 if let Fou::PeerV4(val) = attr? {
160 return Ok(val);
161 }
162 }
163 Err(ErrorContext::new_missing(
164 "Fou",
165 "PeerV4",
166 self.orig_loc,
167 self.buf.as_ptr() as usize,
168 ))
169 }
170 pub fn get_peer_v6(&self) -> Result<&'a [u8], ErrorContext> {
171 let mut iter = self.clone();
172 iter.pos = 0;
173 for attr in iter {
174 if let Fou::PeerV6(val) = attr? {
175 return Ok(val);
176 }
177 }
178 Err(ErrorContext::new_missing(
179 "Fou",
180 "PeerV6",
181 self.orig_loc,
182 self.buf.as_ptr() as usize,
183 ))
184 }
185 pub fn get_peer_port(&self) -> Result<u16, ErrorContext> {
186 let mut iter = self.clone();
187 iter.pos = 0;
188 for attr in iter {
189 if let Fou::PeerPort(val) = attr? {
190 return Ok(val);
191 }
192 }
193 Err(ErrorContext::new_missing(
194 "Fou",
195 "PeerPort",
196 self.orig_loc,
197 self.buf.as_ptr() as usize,
198 ))
199 }
200 pub fn get_ifindex(&self) -> Result<i32, ErrorContext> {
201 let mut iter = self.clone();
202 iter.pos = 0;
203 for attr in iter {
204 if let Fou::Ifindex(val) = attr? {
205 return Ok(val);
206 }
207 }
208 Err(ErrorContext::new_missing(
209 "Fou",
210 "Ifindex",
211 self.orig_loc,
212 self.buf.as_ptr() as usize,
213 ))
214 }
215}
216impl Fou<'_> {
217 pub fn new<'a>(buf: &'a [u8]) -> IterableFou<'a> {
218 IterableFou::with_loc(buf, buf.as_ptr() as usize)
219 }
220 fn attr_from_type(r#type: u16) -> Option<&'static str> {
221 let res = match r#type {
222 0u16 => "Unspec",
223 1u16 => "Port",
224 2u16 => "Af",
225 3u16 => "Ipproto",
226 4u16 => "Type",
227 5u16 => "RemcsumNopartial",
228 6u16 => "LocalV4",
229 7u16 => "LocalV6",
230 8u16 => "PeerV4",
231 9u16 => "PeerV6",
232 10u16 => "PeerPort",
233 11u16 => "Ifindex",
234 _ => return None,
235 };
236 Some(res)
237 }
238}
239#[derive(Clone, Copy, Default)]
240pub struct IterableFou<'a> {
241 buf: &'a [u8],
242 pos: usize,
243 orig_loc: usize,
244}
245impl<'a> IterableFou<'a> {
246 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
247 Self {
248 buf,
249 pos: 0,
250 orig_loc,
251 }
252 }
253 pub fn get_buf(&self) -> &'a [u8] {
254 self.buf
255 }
256}
257impl<'a> Iterator for IterableFou<'a> {
258 type Item = Result<Fou<'a>, ErrorContext>;
259 fn next(&mut self) -> Option<Self::Item> {
260 let pos = self.pos;
261 let mut r#type;
262 loop {
263 r#type = None;
264 if self.buf.len() == self.pos {
265 return None;
266 }
267 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
268 break;
269 };
270 r#type = Some(header.r#type);
271 let res = match header.r#type {
272 1u16 => Fou::Port({
273 let res = parse_be_u16(next);
274 let Some(val) = res else { break };
275 val
276 }),
277 2u16 => Fou::Af({
278 let res = parse_u8(next);
279 let Some(val) = res else { break };
280 val
281 }),
282 3u16 => Fou::Ipproto({
283 let res = parse_u8(next);
284 let Some(val) = res else { break };
285 val
286 }),
287 4u16 => Fou::Type({
288 let res = parse_u8(next);
289 let Some(val) = res else { break };
290 val
291 }),
292 5u16 => Fou::RemcsumNopartial(()),
293 6u16 => Fou::LocalV4({
294 let res = parse_u32(next);
295 let Some(val) = res else { break };
296 val
297 }),
298 7u16 => Fou::LocalV6({
299 let res = Some(next);
300 let Some(val) = res else { break };
301 val
302 }),
303 8u16 => Fou::PeerV4({
304 let res = parse_u32(next);
305 let Some(val) = res else { break };
306 val
307 }),
308 9u16 => Fou::PeerV6({
309 let res = Some(next);
310 let Some(val) = res else { break };
311 val
312 }),
313 10u16 => Fou::PeerPort({
314 let res = parse_be_u16(next);
315 let Some(val) = res else { break };
316 val
317 }),
318 11u16 => Fou::Ifindex({
319 let res = parse_i32(next);
320 let Some(val) = res else { break };
321 val
322 }),
323 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
324 n => continue,
325 };
326 return Some(Ok(res));
327 }
328 Some(Err(ErrorContext::new(
329 "Fou",
330 r#type.and_then(|t| Fou::attr_from_type(t)),
331 self.orig_loc,
332 self.buf.as_ptr().wrapping_add(pos) as usize,
333 )))
334 }
335}
336impl<'a> std::fmt::Debug for IterableFou<'_> {
337 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
338 let mut fmt = f.debug_struct("Fou");
339 for attr in self.clone() {
340 let attr = match attr {
341 Ok(a) => a,
342 Err(err) => {
343 fmt.finish()?;
344 f.write_str("Err(")?;
345 err.fmt(f)?;
346 return f.write_str(")");
347 }
348 };
349 match attr {
350 Fou::Port(val) => fmt.field("Port", &val),
351 Fou::Af(val) => fmt.field("Af", &val),
352 Fou::Ipproto(val) => fmt.field("Ipproto", &val),
353 Fou::Type(val) => fmt.field("Type", &val),
354 Fou::RemcsumNopartial(val) => fmt.field("RemcsumNopartial", &val),
355 Fou::LocalV4(val) => fmt.field("LocalV4", &val),
356 Fou::LocalV6(val) => fmt.field("LocalV6", &val),
357 Fou::PeerV4(val) => fmt.field("PeerV4", &val),
358 Fou::PeerV6(val) => fmt.field("PeerV6", &val),
359 Fou::PeerPort(val) => fmt.field("PeerPort", &val),
360 Fou::Ifindex(val) => fmt.field("Ifindex", &val),
361 };
362 }
363 fmt.finish()
364 }
365}
366impl IterableFou<'_> {
367 pub fn lookup_attr(
368 &self,
369 offset: usize,
370 missing_type: Option<u16>,
371 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
372 let mut stack = Vec::new();
373 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
374 if missing_type.is_some() && cur == offset {
375 stack.push(("Fou", offset));
376 return (stack, missing_type.and_then(|t| Fou::attr_from_type(t)));
377 }
378 if cur > offset || cur + self.buf.len() < offset {
379 return (stack, None);
380 }
381 let mut attrs = self.clone();
382 let mut last_off = cur + attrs.pos;
383 while let Some(attr) = attrs.next() {
384 let Ok(attr) = attr else { break };
385 match attr {
386 Fou::Port(val) => {
387 if last_off == offset {
388 stack.push(("Port", last_off));
389 break;
390 }
391 }
392 Fou::Af(val) => {
393 if last_off == offset {
394 stack.push(("Af", last_off));
395 break;
396 }
397 }
398 Fou::Ipproto(val) => {
399 if last_off == offset {
400 stack.push(("Ipproto", last_off));
401 break;
402 }
403 }
404 Fou::Type(val) => {
405 if last_off == offset {
406 stack.push(("Type", last_off));
407 break;
408 }
409 }
410 Fou::RemcsumNopartial(val) => {
411 if last_off == offset {
412 stack.push(("RemcsumNopartial", last_off));
413 break;
414 }
415 }
416 Fou::LocalV4(val) => {
417 if last_off == offset {
418 stack.push(("LocalV4", last_off));
419 break;
420 }
421 }
422 Fou::LocalV6(val) => {
423 if last_off == offset {
424 stack.push(("LocalV6", last_off));
425 break;
426 }
427 }
428 Fou::PeerV4(val) => {
429 if last_off == offset {
430 stack.push(("PeerV4", last_off));
431 break;
432 }
433 }
434 Fou::PeerV6(val) => {
435 if last_off == offset {
436 stack.push(("PeerV6", last_off));
437 break;
438 }
439 }
440 Fou::PeerPort(val) => {
441 if last_off == offset {
442 stack.push(("PeerPort", last_off));
443 break;
444 }
445 }
446 Fou::Ifindex(val) => {
447 if last_off == offset {
448 stack.push(("Ifindex", last_off));
449 break;
450 }
451 }
452 _ => {}
453 };
454 last_off = cur + attrs.pos;
455 }
456 if !stack.is_empty() {
457 stack.push(("Fou", cur));
458 }
459 (stack, None)
460 }
461}
462pub struct PushFou<Prev: Rec> {
463 pub(crate) prev: Option<Prev>,
464 pub(crate) header_offset: Option<usize>,
465}
466impl<Prev: Rec> Rec for PushFou<Prev> {
467 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
468 self.prev.as_mut().unwrap().as_rec_mut()
469 }
470 fn as_rec(&self) -> &Vec<u8> {
471 self.prev.as_ref().unwrap().as_rec()
472 }
473}
474impl<Prev: Rec> PushFou<Prev> {
475 pub fn new(prev: Prev) -> Self {
476 Self {
477 prev: Some(prev),
478 header_offset: None,
479 }
480 }
481 pub fn end_nested(mut self) -> Prev {
482 let mut prev = self.prev.take().unwrap();
483 if let Some(header_offset) = &self.header_offset {
484 finalize_nested_header(prev.as_rec_mut(), *header_offset);
485 }
486 prev
487 }
488 pub fn push_port(mut self, value: u16) -> Self {
489 push_header(self.as_rec_mut(), 1u16, 2 as u16);
490 self.as_rec_mut().extend(value.to_be_bytes());
491 self
492 }
493 pub fn push_af(mut self, value: u8) -> Self {
494 push_header(self.as_rec_mut(), 2u16, 1 as u16);
495 self.as_rec_mut().extend(value.to_ne_bytes());
496 self
497 }
498 pub fn push_ipproto(mut self, value: u8) -> Self {
499 push_header(self.as_rec_mut(), 3u16, 1 as u16);
500 self.as_rec_mut().extend(value.to_ne_bytes());
501 self
502 }
503 pub fn push_type(mut self, value: u8) -> Self {
504 push_header(self.as_rec_mut(), 4u16, 1 as u16);
505 self.as_rec_mut().extend(value.to_ne_bytes());
506 self
507 }
508 pub fn push_remcsum_nopartial(mut self, value: ()) -> Self {
509 push_header(self.as_rec_mut(), 5u16, 0 as u16);
510 self
511 }
512 pub fn push_local_v4(mut self, value: u32) -> Self {
513 push_header(self.as_rec_mut(), 6u16, 4 as u16);
514 self.as_rec_mut().extend(value.to_ne_bytes());
515 self
516 }
517 pub fn push_local_v6(mut self, value: &[u8]) -> Self {
518 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
519 self.as_rec_mut().extend(value);
520 self
521 }
522 pub fn push_peer_v4(mut self, value: u32) -> Self {
523 push_header(self.as_rec_mut(), 8u16, 4 as u16);
524 self.as_rec_mut().extend(value.to_ne_bytes());
525 self
526 }
527 pub fn push_peer_v6(mut self, value: &[u8]) -> Self {
528 push_header(self.as_rec_mut(), 9u16, value.len() as u16);
529 self.as_rec_mut().extend(value);
530 self
531 }
532 pub fn push_peer_port(mut self, value: u16) -> Self {
533 push_header(self.as_rec_mut(), 10u16, 2 as u16);
534 self.as_rec_mut().extend(value.to_be_bytes());
535 self
536 }
537 pub fn push_ifindex(mut self, value: i32) -> Self {
538 push_header(self.as_rec_mut(), 11u16, 4 as u16);
539 self.as_rec_mut().extend(value.to_ne_bytes());
540 self
541 }
542}
543impl<Prev: Rec> Drop for PushFou<Prev> {
544 fn drop(&mut self) {
545 if let Some(prev) = &mut self.prev {
546 if let Some(header_offset) = &self.header_offset {
547 finalize_nested_header(prev.as_rec_mut(), *header_offset);
548 }
549 }
550 }
551}
552#[doc = "Add port\\.\nFlags: admin-perm\nRequest attributes:\n- [.push_port()](PushFou::push_port)\n- [.push_ipproto()](PushFou::push_ipproto)\n- [.push_type()](PushFou::push_type)\n- [.push_remcsum_nopartial()](PushFou::push_remcsum_nopartial)\n- [.push_local_v4()](PushFou::push_local_v4)\n- [.push_local_v6()](PushFou::push_local_v6)\n- [.push_peer_v4()](PushFou::push_peer_v4)\n- [.push_peer_v6()](PushFou::push_peer_v6)\n- [.push_peer_port()](PushFou::push_peer_port)\n- [.push_ifindex()](PushFou::push_ifindex)\n"]
553#[derive(Debug)]
554pub struct OpAddDo<'r> {
555 request: Request<'r>,
556}
557impl<'r> OpAddDo<'r> {
558 pub fn new(mut request: Request<'r>) -> Self {
559 Self::write_header(request.buf_mut());
560 Self { request: request }
561 }
562 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushFou<&'buf mut Vec<u8>> {
563 Self::write_header(buf);
564 PushFou::new(buf)
565 }
566 pub fn encode(&mut self) -> PushFou<&mut Vec<u8>> {
567 PushFou::new(self.request.buf_mut())
568 }
569 pub fn into_encoder(self) -> PushFou<RequestBuf<'r>> {
570 PushFou::new(self.request.buf)
571 }
572 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableFou<'a> {
573 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
574 IterableFou::with_loc(attrs, buf.as_ptr() as usize)
575 }
576 fn write_header<Prev: Rec>(prev: &mut Prev) {
577 let mut header = BuiltinNfgenmsg::new();
578 header.cmd = 1u8;
579 header.version = 1u8;
580 prev.as_rec_mut().extend(header.as_slice());
581 }
582}
583impl NetlinkRequest for OpAddDo<'_> {
584 fn protocol(&self) -> Protocol {
585 Protocol::Generic("fou".as_bytes())
586 }
587 fn flags(&self) -> u16 {
588 self.request.flags
589 }
590 fn payload(&self) -> &[u8] {
591 self.request.buf()
592 }
593 type ReplyType<'buf> = IterableFou<'buf>;
594 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
595 Self::decode_request(buf)
596 }
597 fn lookup(
598 buf: &[u8],
599 offset: usize,
600 missing_type: Option<u16>,
601 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
602 Self::decode_request(buf).lookup_attr(offset, missing_type)
603 }
604}
605#[doc = "Delete port\\.\nFlags: admin-perm\nRequest attributes:\n- [.push_port()](PushFou::push_port)\n- [.push_af()](PushFou::push_af)\n- [.push_local_v4()](PushFou::push_local_v4)\n- [.push_local_v6()](PushFou::push_local_v6)\n- [.push_peer_v4()](PushFou::push_peer_v4)\n- [.push_peer_v6()](PushFou::push_peer_v6)\n- [.push_peer_port()](PushFou::push_peer_port)\n- [.push_ifindex()](PushFou::push_ifindex)\n"]
606#[derive(Debug)]
607pub struct OpDelDo<'r> {
608 request: Request<'r>,
609}
610impl<'r> OpDelDo<'r> {
611 pub fn new(mut request: Request<'r>) -> Self {
612 Self::write_header(request.buf_mut());
613 Self { request: request }
614 }
615 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushFou<&'buf mut Vec<u8>> {
616 Self::write_header(buf);
617 PushFou::new(buf)
618 }
619 pub fn encode(&mut self) -> PushFou<&mut Vec<u8>> {
620 PushFou::new(self.request.buf_mut())
621 }
622 pub fn into_encoder(self) -> PushFou<RequestBuf<'r>> {
623 PushFou::new(self.request.buf)
624 }
625 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableFou<'a> {
626 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
627 IterableFou::with_loc(attrs, buf.as_ptr() as usize)
628 }
629 fn write_header<Prev: Rec>(prev: &mut Prev) {
630 let mut header = BuiltinNfgenmsg::new();
631 header.cmd = 2u8;
632 header.version = 1u8;
633 prev.as_rec_mut().extend(header.as_slice());
634 }
635}
636impl NetlinkRequest for OpDelDo<'_> {
637 fn protocol(&self) -> Protocol {
638 Protocol::Generic("fou".as_bytes())
639 }
640 fn flags(&self) -> u16 {
641 self.request.flags
642 }
643 fn payload(&self) -> &[u8] {
644 self.request.buf()
645 }
646 type ReplyType<'buf> = IterableFou<'buf>;
647 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
648 Self::decode_request(buf)
649 }
650 fn lookup(
651 buf: &[u8],
652 offset: usize,
653 missing_type: Option<u16>,
654 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
655 Self::decode_request(buf).lookup_attr(offset, missing_type)
656 }
657}
658#[doc = "Get tunnel info\\.\n\nReply attributes:\n- [.get_port()](IterableFou::get_port)\n- [.get_ipproto()](IterableFou::get_ipproto)\n- [.get_type()](IterableFou::get_type)\n- [.get_remcsum_nopartial()](IterableFou::get_remcsum_nopartial)\n- [.get_local_v4()](IterableFou::get_local_v4)\n- [.get_local_v6()](IterableFou::get_local_v6)\n- [.get_peer_v4()](IterableFou::get_peer_v4)\n- [.get_peer_v6()](IterableFou::get_peer_v6)\n- [.get_peer_port()](IterableFou::get_peer_port)\n- [.get_ifindex()](IterableFou::get_ifindex)\n"]
659#[derive(Debug)]
660pub struct OpGetDump<'r> {
661 request: Request<'r>,
662}
663impl<'r> OpGetDump<'r> {
664 pub fn new(mut request: Request<'r>) -> Self {
665 Self::write_header(request.buf_mut());
666 Self {
667 request: request.set_dump(),
668 }
669 }
670 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushFou<&'buf mut Vec<u8>> {
671 Self::write_header(buf);
672 PushFou::new(buf)
673 }
674 pub fn encode(&mut self) -> PushFou<&mut Vec<u8>> {
675 PushFou::new(self.request.buf_mut())
676 }
677 pub fn into_encoder(self) -> PushFou<RequestBuf<'r>> {
678 PushFou::new(self.request.buf)
679 }
680 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableFou<'a> {
681 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
682 IterableFou::with_loc(attrs, buf.as_ptr() as usize)
683 }
684 fn write_header<Prev: Rec>(prev: &mut Prev) {
685 let mut header = BuiltinNfgenmsg::new();
686 header.cmd = 3u8;
687 header.version = 1u8;
688 prev.as_rec_mut().extend(header.as_slice());
689 }
690}
691impl NetlinkRequest for OpGetDump<'_> {
692 fn protocol(&self) -> Protocol {
693 Protocol::Generic("fou".as_bytes())
694 }
695 fn flags(&self) -> u16 {
696 self.request.flags
697 }
698 fn payload(&self) -> &[u8] {
699 self.request.buf()
700 }
701 type ReplyType<'buf> = IterableFou<'buf>;
702 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
703 Self::decode_request(buf)
704 }
705 fn lookup(
706 buf: &[u8],
707 offset: usize,
708 missing_type: Option<u16>,
709 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
710 Self::decode_request(buf).lookup_attr(offset, missing_type)
711 }
712}
713#[doc = "Get tunnel info\\.\nRequest attributes:\n- [.push_port()](PushFou::push_port)\n- [.push_af()](PushFou::push_af)\n- [.push_local_v4()](PushFou::push_local_v4)\n- [.push_local_v6()](PushFou::push_local_v6)\n- [.push_peer_v4()](PushFou::push_peer_v4)\n- [.push_peer_v6()](PushFou::push_peer_v6)\n- [.push_peer_port()](PushFou::push_peer_port)\n- [.push_ifindex()](PushFou::push_ifindex)\n\nReply attributes:\n- [.get_port()](IterableFou::get_port)\n- [.get_ipproto()](IterableFou::get_ipproto)\n- [.get_type()](IterableFou::get_type)\n- [.get_remcsum_nopartial()](IterableFou::get_remcsum_nopartial)\n- [.get_local_v4()](IterableFou::get_local_v4)\n- [.get_local_v6()](IterableFou::get_local_v6)\n- [.get_peer_v4()](IterableFou::get_peer_v4)\n- [.get_peer_v6()](IterableFou::get_peer_v6)\n- [.get_peer_port()](IterableFou::get_peer_port)\n- [.get_ifindex()](IterableFou::get_ifindex)\n"]
714#[derive(Debug)]
715pub struct OpGetDo<'r> {
716 request: Request<'r>,
717}
718impl<'r> OpGetDo<'r> {
719 pub fn new(mut request: Request<'r>) -> Self {
720 Self::write_header(request.buf_mut());
721 Self { request: request }
722 }
723 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushFou<&'buf mut Vec<u8>> {
724 Self::write_header(buf);
725 PushFou::new(buf)
726 }
727 pub fn encode(&mut self) -> PushFou<&mut Vec<u8>> {
728 PushFou::new(self.request.buf_mut())
729 }
730 pub fn into_encoder(self) -> PushFou<RequestBuf<'r>> {
731 PushFou::new(self.request.buf)
732 }
733 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableFou<'a> {
734 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
735 IterableFou::with_loc(attrs, buf.as_ptr() as usize)
736 }
737 fn write_header<Prev: Rec>(prev: &mut Prev) {
738 let mut header = BuiltinNfgenmsg::new();
739 header.cmd = 3u8;
740 header.version = 1u8;
741 prev.as_rec_mut().extend(header.as_slice());
742 }
743}
744impl NetlinkRequest for OpGetDo<'_> {
745 fn protocol(&self) -> Protocol {
746 Protocol::Generic("fou".as_bytes())
747 }
748 fn flags(&self) -> u16 {
749 self.request.flags
750 }
751 fn payload(&self) -> &[u8] {
752 self.request.buf()
753 }
754 type ReplyType<'buf> = IterableFou<'buf>;
755 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
756 Self::decode_request(buf)
757 }
758 fn lookup(
759 buf: &[u8],
760 offset: usize,
761 missing_type: Option<u16>,
762 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
763 Self::decode_request(buf).lookup_attr(offset, missing_type)
764 }
765}
766use crate::traits::LookupFn;
767use crate::utils::RequestBuf;
768#[derive(Debug)]
769pub struct Request<'buf> {
770 buf: RequestBuf<'buf>,
771 flags: u16,
772 writeback: Option<&'buf mut Option<RequestInfo>>,
773}
774#[allow(unused)]
775#[derive(Debug, Clone)]
776pub struct RequestInfo {
777 protocol: Protocol,
778 flags: u16,
779 name: &'static str,
780 lookup: LookupFn,
781}
782impl Request<'static> {
783 pub fn new() -> Self {
784 Self::new_from_buf(Vec::new())
785 }
786 pub fn new_from_buf(buf: Vec<u8>) -> Self {
787 Self {
788 flags: 0,
789 buf: RequestBuf::Own(buf),
790 writeback: None,
791 }
792 }
793 pub fn into_buf(self) -> Vec<u8> {
794 match self.buf {
795 RequestBuf::Own(buf) => buf,
796 _ => unreachable!(),
797 }
798 }
799}
800impl<'buf> Request<'buf> {
801 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
802 buf.clear();
803 Self::new_extend(buf)
804 }
805 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
806 Self {
807 flags: 0,
808 buf: RequestBuf::Ref(buf),
809 writeback: None,
810 }
811 }
812 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
813 let Some(writeback) = &mut self.writeback else {
814 return;
815 };
816 **writeback = Some(RequestInfo {
817 protocol,
818 flags: self.flags,
819 name,
820 lookup,
821 })
822 }
823 pub fn buf(&self) -> &Vec<u8> {
824 self.buf.buf()
825 }
826 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
827 self.buf.buf_mut()
828 }
829 #[doc = "Set `NLM_F_CREATE` flag"]
830 pub fn set_create(mut self) -> Self {
831 self.flags |= consts::NLM_F_CREATE as u16;
832 self
833 }
834 #[doc = "Set `NLM_F_EXCL` flag"]
835 pub fn set_excl(mut self) -> Self {
836 self.flags |= consts::NLM_F_EXCL as u16;
837 self
838 }
839 #[doc = "Set `NLM_F_REPLACE` flag"]
840 pub fn set_replace(mut self) -> Self {
841 self.flags |= consts::NLM_F_REPLACE as u16;
842 self
843 }
844 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
845 pub fn set_change(self) -> Self {
846 self.set_create().set_replace()
847 }
848 #[doc = "Set `NLM_F_APPEND` flag"]
849 pub fn set_append(mut self) -> Self {
850 self.flags |= consts::NLM_F_APPEND as u16;
851 self
852 }
853 #[doc = "Set `self.flags |= flags`"]
854 pub fn set_flags(mut self, flags: u16) -> Self {
855 self.flags |= flags;
856 self
857 }
858 #[doc = "Set `self.flags ^= self.flags & flags`"]
859 pub fn unset_flags(mut self, flags: u16) -> Self {
860 self.flags ^= self.flags & flags;
861 self
862 }
863 #[doc = "Set `NLM_F_DUMP` flag"]
864 fn set_dump(mut self) -> Self {
865 self.flags |= consts::NLM_F_DUMP as u16;
866 self
867 }
868 #[doc = "Add port\\.\nFlags: admin-perm\nRequest attributes:\n- [.push_port()](PushFou::push_port)\n- [.push_ipproto()](PushFou::push_ipproto)\n- [.push_type()](PushFou::push_type)\n- [.push_remcsum_nopartial()](PushFou::push_remcsum_nopartial)\n- [.push_local_v4()](PushFou::push_local_v4)\n- [.push_local_v6()](PushFou::push_local_v6)\n- [.push_peer_v4()](PushFou::push_peer_v4)\n- [.push_peer_v6()](PushFou::push_peer_v6)\n- [.push_peer_port()](PushFou::push_peer_port)\n- [.push_ifindex()](PushFou::push_ifindex)\n"]
869 pub fn op_add_do(self) -> OpAddDo<'buf> {
870 let mut res = OpAddDo::new(self);
871 res.request
872 .do_writeback(res.protocol(), "op-add-do", OpAddDo::lookup);
873 res
874 }
875 #[doc = "Delete port\\.\nFlags: admin-perm\nRequest attributes:\n- [.push_port()](PushFou::push_port)\n- [.push_af()](PushFou::push_af)\n- [.push_local_v4()](PushFou::push_local_v4)\n- [.push_local_v6()](PushFou::push_local_v6)\n- [.push_peer_v4()](PushFou::push_peer_v4)\n- [.push_peer_v6()](PushFou::push_peer_v6)\n- [.push_peer_port()](PushFou::push_peer_port)\n- [.push_ifindex()](PushFou::push_ifindex)\n"]
876 pub fn op_del_do(self) -> OpDelDo<'buf> {
877 let mut res = OpDelDo::new(self);
878 res.request
879 .do_writeback(res.protocol(), "op-del-do", OpDelDo::lookup);
880 res
881 }
882 #[doc = "Get tunnel info\\.\n\nReply attributes:\n- [.get_port()](IterableFou::get_port)\n- [.get_ipproto()](IterableFou::get_ipproto)\n- [.get_type()](IterableFou::get_type)\n- [.get_remcsum_nopartial()](IterableFou::get_remcsum_nopartial)\n- [.get_local_v4()](IterableFou::get_local_v4)\n- [.get_local_v6()](IterableFou::get_local_v6)\n- [.get_peer_v4()](IterableFou::get_peer_v4)\n- [.get_peer_v6()](IterableFou::get_peer_v6)\n- [.get_peer_port()](IterableFou::get_peer_port)\n- [.get_ifindex()](IterableFou::get_ifindex)\n"]
883 pub fn op_get_dump(self) -> OpGetDump<'buf> {
884 let mut res = OpGetDump::new(self);
885 res.request
886 .do_writeback(res.protocol(), "op-get-dump", OpGetDump::lookup);
887 res
888 }
889 #[doc = "Get tunnel info\\.\nRequest attributes:\n- [.push_port()](PushFou::push_port)\n- [.push_af()](PushFou::push_af)\n- [.push_local_v4()](PushFou::push_local_v4)\n- [.push_local_v6()](PushFou::push_local_v6)\n- [.push_peer_v4()](PushFou::push_peer_v4)\n- [.push_peer_v6()](PushFou::push_peer_v6)\n- [.push_peer_port()](PushFou::push_peer_port)\n- [.push_ifindex()](PushFou::push_ifindex)\n\nReply attributes:\n- [.get_port()](IterableFou::get_port)\n- [.get_ipproto()](IterableFou::get_ipproto)\n- [.get_type()](IterableFou::get_type)\n- [.get_remcsum_nopartial()](IterableFou::get_remcsum_nopartial)\n- [.get_local_v4()](IterableFou::get_local_v4)\n- [.get_local_v6()](IterableFou::get_local_v6)\n- [.get_peer_v4()](IterableFou::get_peer_v4)\n- [.get_peer_v6()](IterableFou::get_peer_v6)\n- [.get_peer_port()](IterableFou::get_peer_port)\n- [.get_ifindex()](IterableFou::get_ifindex)\n"]
890 pub fn op_get_do(self) -> OpGetDo<'buf> {
891 let mut res = OpGetDo::new(self);
892 res.request
893 .do_writeback(res.protocol(), "op-get-do", OpGetDo::lookup);
894 res
895 }
896}
897#[cfg(test)]
898mod generated_tests {
899 use super::*;
900 #[test]
901 fn tests() {
902 let _ = IterableFou::get_ifindex;
903 let _ = IterableFou::get_ipproto;
904 let _ = IterableFou::get_local_v4;
905 let _ = IterableFou::get_local_v6;
906 let _ = IterableFou::get_peer_port;
907 let _ = IterableFou::get_peer_v4;
908 let _ = IterableFou::get_peer_v6;
909 let _ = IterableFou::get_port;
910 let _ = IterableFou::get_remcsum_nopartial;
911 let _ = IterableFou::get_type;
912 let _ = PushFou::<&mut Vec<u8>>::push_af;
913 let _ = PushFou::<&mut Vec<u8>>::push_ifindex;
914 let _ = PushFou::<&mut Vec<u8>>::push_ipproto;
915 let _ = PushFou::<&mut Vec<u8>>::push_local_v4;
916 let _ = PushFou::<&mut Vec<u8>>::push_local_v6;
917 let _ = PushFou::<&mut Vec<u8>>::push_peer_port;
918 let _ = PushFou::<&mut Vec<u8>>::push_peer_v4;
919 let _ = PushFou::<&mut Vec<u8>>::push_peer_v6;
920 let _ = PushFou::<&mut Vec<u8>>::push_port;
921 let _ = PushFou::<&mut Vec<u8>>::push_remcsum_nopartial;
922 let _ = PushFou::<&mut Vec<u8>>::push_type;
923 }
924}