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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 mut pos;
261 let mut r#type;
262 loop {
263 pos = self.pos;
264 r#type = None;
265 if self.buf.len() == self.pos {
266 return None;
267 }
268 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
269 self.pos = self.buf.len();
270 break;
271 };
272 r#type = Some(header.r#type);
273 let res = match header.r#type {
274 1u16 => Fou::Port({
275 let res = parse_be_u16(next);
276 let Some(val) = res else { break };
277 val
278 }),
279 2u16 => Fou::Af({
280 let res = parse_u8(next);
281 let Some(val) = res else { break };
282 val
283 }),
284 3u16 => Fou::Ipproto({
285 let res = parse_u8(next);
286 let Some(val) = res else { break };
287 val
288 }),
289 4u16 => Fou::Type({
290 let res = parse_u8(next);
291 let Some(val) = res else { break };
292 val
293 }),
294 5u16 => Fou::RemcsumNopartial(()),
295 6u16 => Fou::LocalV4({
296 let res = parse_u32(next);
297 let Some(val) = res else { break };
298 val
299 }),
300 7u16 => Fou::LocalV6({
301 let res = Some(next);
302 let Some(val) = res else { break };
303 val
304 }),
305 8u16 => Fou::PeerV4({
306 let res = parse_u32(next);
307 let Some(val) = res else { break };
308 val
309 }),
310 9u16 => Fou::PeerV6({
311 let res = Some(next);
312 let Some(val) = res else { break };
313 val
314 }),
315 10u16 => Fou::PeerPort({
316 let res = parse_be_u16(next);
317 let Some(val) = res else { break };
318 val
319 }),
320 11u16 => Fou::Ifindex({
321 let res = parse_i32(next);
322 let Some(val) = res else { break };
323 val
324 }),
325 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
326 n => continue,
327 };
328 return Some(Ok(res));
329 }
330 Some(Err(ErrorContext::new(
331 "Fou",
332 r#type.and_then(|t| Fou::attr_from_type(t)),
333 self.orig_loc,
334 self.buf.as_ptr().wrapping_add(pos) as usize,
335 )))
336 }
337}
338impl<'a> std::fmt::Debug for IterableFou<'_> {
339 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
340 let mut fmt = f.debug_struct("Fou");
341 for attr in self.clone() {
342 let attr = match attr {
343 Ok(a) => a,
344 Err(err) => {
345 fmt.finish()?;
346 f.write_str("Err(")?;
347 err.fmt(f)?;
348 return f.write_str(")");
349 }
350 };
351 match attr {
352 Fou::Port(val) => fmt.field("Port", &val),
353 Fou::Af(val) => fmt.field("Af", &val),
354 Fou::Ipproto(val) => fmt.field("Ipproto", &val),
355 Fou::Type(val) => fmt.field("Type", &val),
356 Fou::RemcsumNopartial(val) => fmt.field("RemcsumNopartial", &val),
357 Fou::LocalV4(val) => fmt.field("LocalV4", &val),
358 Fou::LocalV6(val) => fmt.field("LocalV6", &val),
359 Fou::PeerV4(val) => fmt.field("PeerV4", &val),
360 Fou::PeerV6(val) => fmt.field("PeerV6", &val),
361 Fou::PeerPort(val) => fmt.field("PeerPort", &val),
362 Fou::Ifindex(val) => fmt.field("Ifindex", &val),
363 };
364 }
365 fmt.finish()
366 }
367}
368impl IterableFou<'_> {
369 pub fn lookup_attr(
370 &self,
371 offset: usize,
372 missing_type: Option<u16>,
373 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
374 let mut stack = Vec::new();
375 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
376 if missing_type.is_some() && cur == offset {
377 stack.push(("Fou", offset));
378 return (stack, missing_type.and_then(|t| Fou::attr_from_type(t)));
379 }
380 if cur > offset || cur + self.buf.len() < offset {
381 return (stack, None);
382 }
383 let mut attrs = self.clone();
384 let mut last_off = cur + attrs.pos;
385 while let Some(attr) = attrs.next() {
386 let Ok(attr) = attr else { break };
387 match attr {
388 Fou::Port(val) => {
389 if last_off == offset {
390 stack.push(("Port", last_off));
391 break;
392 }
393 }
394 Fou::Af(val) => {
395 if last_off == offset {
396 stack.push(("Af", last_off));
397 break;
398 }
399 }
400 Fou::Ipproto(val) => {
401 if last_off == offset {
402 stack.push(("Ipproto", last_off));
403 break;
404 }
405 }
406 Fou::Type(val) => {
407 if last_off == offset {
408 stack.push(("Type", last_off));
409 break;
410 }
411 }
412 Fou::RemcsumNopartial(val) => {
413 if last_off == offset {
414 stack.push(("RemcsumNopartial", last_off));
415 break;
416 }
417 }
418 Fou::LocalV4(val) => {
419 if last_off == offset {
420 stack.push(("LocalV4", last_off));
421 break;
422 }
423 }
424 Fou::LocalV6(val) => {
425 if last_off == offset {
426 stack.push(("LocalV6", last_off));
427 break;
428 }
429 }
430 Fou::PeerV4(val) => {
431 if last_off == offset {
432 stack.push(("PeerV4", last_off));
433 break;
434 }
435 }
436 Fou::PeerV6(val) => {
437 if last_off == offset {
438 stack.push(("PeerV6", last_off));
439 break;
440 }
441 }
442 Fou::PeerPort(val) => {
443 if last_off == offset {
444 stack.push(("PeerPort", last_off));
445 break;
446 }
447 }
448 Fou::Ifindex(val) => {
449 if last_off == offset {
450 stack.push(("Ifindex", last_off));
451 break;
452 }
453 }
454 _ => {}
455 };
456 last_off = cur + attrs.pos;
457 }
458 if !stack.is_empty() {
459 stack.push(("Fou", cur));
460 }
461 (stack, None)
462 }
463}
464pub struct PushFou<Prev: Pusher> {
465 pub(crate) prev: Option<Prev>,
466 pub(crate) header_offset: Option<usize>,
467}
468impl<Prev: Pusher> Pusher for PushFou<Prev> {
469 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
470 self.prev.as_mut().unwrap().as_vec_mut()
471 }
472 fn as_vec(&self) -> &Vec<u8> {
473 self.prev.as_ref().unwrap().as_vec()
474 }
475}
476impl<Prev: Pusher> PushFou<Prev> {
477 pub fn new(prev: Prev) -> Self {
478 Self {
479 prev: Some(prev),
480 header_offset: None,
481 }
482 }
483 pub fn end_nested(mut self) -> Prev {
484 let mut prev = self.prev.take().unwrap();
485 if let Some(header_offset) = &self.header_offset {
486 finalize_nested_header(prev.as_vec_mut(), *header_offset);
487 }
488 prev
489 }
490 pub fn push_port(mut self, value: u16) -> Self {
491 push_header(self.as_vec_mut(), 1u16, 2 as u16);
492 self.as_vec_mut().extend(value.to_be_bytes());
493 self
494 }
495 pub fn push_af(mut self, value: u8) -> Self {
496 push_header(self.as_vec_mut(), 2u16, 1 as u16);
497 self.as_vec_mut().extend(value.to_ne_bytes());
498 self
499 }
500 pub fn push_ipproto(mut self, value: u8) -> Self {
501 push_header(self.as_vec_mut(), 3u16, 1 as u16);
502 self.as_vec_mut().extend(value.to_ne_bytes());
503 self
504 }
505 pub fn push_type(mut self, value: u8) -> Self {
506 push_header(self.as_vec_mut(), 4u16, 1 as u16);
507 self.as_vec_mut().extend(value.to_ne_bytes());
508 self
509 }
510 pub fn push_remcsum_nopartial(mut self, value: ()) -> Self {
511 push_header(self.as_vec_mut(), 5u16, 0 as u16);
512 self
513 }
514 pub fn push_local_v4(mut self, value: u32) -> Self {
515 push_header(self.as_vec_mut(), 6u16, 4 as u16);
516 self.as_vec_mut().extend(value.to_ne_bytes());
517 self
518 }
519 pub fn push_local_v6(mut self, value: &[u8]) -> Self {
520 push_header(self.as_vec_mut(), 7u16, value.len() as u16);
521 self.as_vec_mut().extend(value);
522 self
523 }
524 pub fn push_peer_v4(mut self, value: u32) -> Self {
525 push_header(self.as_vec_mut(), 8u16, 4 as u16);
526 self.as_vec_mut().extend(value.to_ne_bytes());
527 self
528 }
529 pub fn push_peer_v6(mut self, value: &[u8]) -> Self {
530 push_header(self.as_vec_mut(), 9u16, value.len() as u16);
531 self.as_vec_mut().extend(value);
532 self
533 }
534 pub fn push_peer_port(mut self, value: u16) -> Self {
535 push_header(self.as_vec_mut(), 10u16, 2 as u16);
536 self.as_vec_mut().extend(value.to_be_bytes());
537 self
538 }
539 pub fn push_ifindex(mut self, value: i32) -> Self {
540 push_header(self.as_vec_mut(), 11u16, 4 as u16);
541 self.as_vec_mut().extend(value.to_ne_bytes());
542 self
543 }
544}
545impl<Prev: Pusher> Drop for PushFou<Prev> {
546 fn drop(&mut self) {
547 if let Some(prev) = &mut self.prev {
548 if let Some(header_offset) = &self.header_offset {
549 finalize_nested_header(prev.as_vec_mut(), *header_offset);
550 }
551 }
552 }
553}
554#[doc = "Add port.\n\nFlags: admin-perm\n\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\n"]
555#[derive(Debug)]
556pub struct OpAddDo<'r> {
557 request: Request<'r>,
558}
559impl<'r> OpAddDo<'r> {
560 pub fn new(mut request: Request<'r>) -> Self {
561 Self::write_header(request.buf_mut());
562 Self { request: request }
563 }
564 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushFou<&'buf mut Vec<u8>> {
565 Self::write_header(buf);
566 PushFou::new(buf)
567 }
568 pub fn encode(&mut self) -> PushFou<&mut Vec<u8>> {
569 PushFou::new(self.request.buf_mut())
570 }
571 pub fn into_encoder(self) -> PushFou<RequestBuf<'r>> {
572 PushFou::new(self.request.buf)
573 }
574 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableFou<'a> {
575 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
576 IterableFou::with_loc(attrs, buf.as_ptr() as usize)
577 }
578 fn write_header<Prev: Pusher>(prev: &mut Prev) {
579 let mut header = BuiltinNfgenmsg::new();
580 header.cmd = 1u8;
581 header.version = 1u8;
582 prev.as_vec_mut().extend(header.as_slice());
583 }
584}
585impl NetlinkRequest for OpAddDo<'_> {
586 fn protocol(&self) -> Protocol {
587 Protocol::Generic("fou".as_bytes())
588 }
589 fn flags(&self) -> u16 {
590 self.request.flags
591 }
592 fn payload(&self) -> &[u8] {
593 self.request.buf()
594 }
595 type ReplyType<'buf> = IterableFou<'buf>;
596 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
597 Self::decode_request(buf)
598 }
599 fn lookup(
600 buf: &[u8],
601 offset: usize,
602 missing_type: Option<u16>,
603 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
604 Self::decode_request(buf).lookup_attr(offset, missing_type)
605 }
606}
607#[doc = "Delete port.\n\nFlags: admin-perm\n\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\n"]
608#[derive(Debug)]
609pub struct OpDelDo<'r> {
610 request: Request<'r>,
611}
612impl<'r> OpDelDo<'r> {
613 pub fn new(mut request: Request<'r>) -> Self {
614 Self::write_header(request.buf_mut());
615 Self { request: request }
616 }
617 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushFou<&'buf mut Vec<u8>> {
618 Self::write_header(buf);
619 PushFou::new(buf)
620 }
621 pub fn encode(&mut self) -> PushFou<&mut Vec<u8>> {
622 PushFou::new(self.request.buf_mut())
623 }
624 pub fn into_encoder(self) -> PushFou<RequestBuf<'r>> {
625 PushFou::new(self.request.buf)
626 }
627 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableFou<'a> {
628 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
629 IterableFou::with_loc(attrs, buf.as_ptr() as usize)
630 }
631 fn write_header<Prev: Pusher>(prev: &mut Prev) {
632 let mut header = BuiltinNfgenmsg::new();
633 header.cmd = 2u8;
634 header.version = 1u8;
635 prev.as_vec_mut().extend(header.as_slice());
636 }
637}
638impl NetlinkRequest for OpDelDo<'_> {
639 fn protocol(&self) -> Protocol {
640 Protocol::Generic("fou".as_bytes())
641 }
642 fn flags(&self) -> u16 {
643 self.request.flags
644 }
645 fn payload(&self) -> &[u8] {
646 self.request.buf()
647 }
648 type ReplyType<'buf> = IterableFou<'buf>;
649 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
650 Self::decode_request(buf)
651 }
652 fn lookup(
653 buf: &[u8],
654 offset: usize,
655 missing_type: Option<u16>,
656 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
657 Self::decode_request(buf).lookup_attr(offset, missing_type)
658 }
659}
660#[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\n"]
661#[derive(Debug)]
662pub struct OpGetDump<'r> {
663 request: Request<'r>,
664}
665impl<'r> OpGetDump<'r> {
666 pub fn new(mut request: Request<'r>) -> Self {
667 Self::write_header(request.buf_mut());
668 Self {
669 request: request.set_dump(),
670 }
671 }
672 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushFou<&'buf mut Vec<u8>> {
673 Self::write_header(buf);
674 PushFou::new(buf)
675 }
676 pub fn encode(&mut self) -> PushFou<&mut Vec<u8>> {
677 PushFou::new(self.request.buf_mut())
678 }
679 pub fn into_encoder(self) -> PushFou<RequestBuf<'r>> {
680 PushFou::new(self.request.buf)
681 }
682 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableFou<'a> {
683 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
684 IterableFou::with_loc(attrs, buf.as_ptr() as usize)
685 }
686 fn write_header<Prev: Pusher>(prev: &mut Prev) {
687 let mut header = BuiltinNfgenmsg::new();
688 header.cmd = 3u8;
689 header.version = 1u8;
690 prev.as_vec_mut().extend(header.as_slice());
691 }
692}
693impl NetlinkRequest for OpGetDump<'_> {
694 fn protocol(&self) -> Protocol {
695 Protocol::Generic("fou".as_bytes())
696 }
697 fn flags(&self) -> u16 {
698 self.request.flags
699 }
700 fn payload(&self) -> &[u8] {
701 self.request.buf()
702 }
703 type ReplyType<'buf> = IterableFou<'buf>;
704 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
705 Self::decode_request(buf)
706 }
707 fn lookup(
708 buf: &[u8],
709 offset: usize,
710 missing_type: Option<u16>,
711 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
712 Self::decode_request(buf).lookup_attr(offset, missing_type)
713 }
714}
715#[doc = "Get tunnel info.\n\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\n"]
716#[derive(Debug)]
717pub struct OpGetDo<'r> {
718 request: Request<'r>,
719}
720impl<'r> OpGetDo<'r> {
721 pub fn new(mut request: Request<'r>) -> Self {
722 Self::write_header(request.buf_mut());
723 Self { request: request }
724 }
725 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushFou<&'buf mut Vec<u8>> {
726 Self::write_header(buf);
727 PushFou::new(buf)
728 }
729 pub fn encode(&mut self) -> PushFou<&mut Vec<u8>> {
730 PushFou::new(self.request.buf_mut())
731 }
732 pub fn into_encoder(self) -> PushFou<RequestBuf<'r>> {
733 PushFou::new(self.request.buf)
734 }
735 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableFou<'a> {
736 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
737 IterableFou::with_loc(attrs, buf.as_ptr() as usize)
738 }
739 fn write_header<Prev: Pusher>(prev: &mut Prev) {
740 let mut header = BuiltinNfgenmsg::new();
741 header.cmd = 3u8;
742 header.version = 1u8;
743 prev.as_vec_mut().extend(header.as_slice());
744 }
745}
746impl NetlinkRequest for OpGetDo<'_> {
747 fn protocol(&self) -> Protocol {
748 Protocol::Generic("fou".as_bytes())
749 }
750 fn flags(&self) -> u16 {
751 self.request.flags
752 }
753 fn payload(&self) -> &[u8] {
754 self.request.buf()
755 }
756 type ReplyType<'buf> = IterableFou<'buf>;
757 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
758 Self::decode_request(buf)
759 }
760 fn lookup(
761 buf: &[u8],
762 offset: usize,
763 missing_type: Option<u16>,
764 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
765 Self::decode_request(buf).lookup_attr(offset, missing_type)
766 }
767}
768use crate::traits::LookupFn;
769use crate::utils::RequestBuf;
770#[derive(Debug)]
771pub struct Request<'buf> {
772 buf: RequestBuf<'buf>,
773 flags: u16,
774 writeback: Option<&'buf mut Option<RequestInfo>>,
775}
776#[allow(unused)]
777#[derive(Debug, Clone)]
778pub struct RequestInfo {
779 protocol: Protocol,
780 flags: u16,
781 name: &'static str,
782 lookup: LookupFn,
783}
784impl Request<'static> {
785 pub fn new() -> Self {
786 Self::new_from_buf(Vec::new())
787 }
788 pub fn new_from_buf(buf: Vec<u8>) -> Self {
789 Self {
790 flags: 0,
791 buf: RequestBuf::Own(buf),
792 writeback: None,
793 }
794 }
795 pub fn into_buf(self) -> Vec<u8> {
796 match self.buf {
797 RequestBuf::Own(buf) => buf,
798 _ => unreachable!(),
799 }
800 }
801}
802impl<'buf> Request<'buf> {
803 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
804 buf.clear();
805 Self::new_extend(buf)
806 }
807 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
808 Self {
809 flags: 0,
810 buf: RequestBuf::Ref(buf),
811 writeback: None,
812 }
813 }
814 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
815 let Some(writeback) = &mut self.writeback else {
816 return;
817 };
818 **writeback = Some(RequestInfo {
819 protocol,
820 flags: self.flags,
821 name,
822 lookup,
823 })
824 }
825 pub fn buf(&self) -> &Vec<u8> {
826 self.buf.buf()
827 }
828 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
829 self.buf.buf_mut()
830 }
831 #[doc = "Set `NLM_F_CREATE` flag"]
832 pub fn set_create(mut self) -> Self {
833 self.flags |= consts::NLM_F_CREATE as u16;
834 self
835 }
836 #[doc = "Set `NLM_F_EXCL` flag"]
837 pub fn set_excl(mut self) -> Self {
838 self.flags |= consts::NLM_F_EXCL as u16;
839 self
840 }
841 #[doc = "Set `NLM_F_REPLACE` flag"]
842 pub fn set_replace(mut self) -> Self {
843 self.flags |= consts::NLM_F_REPLACE as u16;
844 self
845 }
846 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
847 pub fn set_change(self) -> Self {
848 self.set_create().set_replace()
849 }
850 #[doc = "Set `NLM_F_APPEND` flag"]
851 pub fn set_append(mut self) -> Self {
852 self.flags |= consts::NLM_F_APPEND as u16;
853 self
854 }
855 #[doc = "Set `self.flags |= flags`"]
856 pub fn set_flags(mut self, flags: u16) -> Self {
857 self.flags |= flags;
858 self
859 }
860 #[doc = "Set `self.flags ^= self.flags & flags`"]
861 pub fn unset_flags(mut self, flags: u16) -> Self {
862 self.flags ^= self.flags & flags;
863 self
864 }
865 #[doc = "Set `NLM_F_DUMP` flag"]
866 fn set_dump(mut self) -> Self {
867 self.flags |= consts::NLM_F_DUMP as u16;
868 self
869 }
870 #[doc = "Add port.\n\nFlags: admin-perm\n\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\n"]
871 pub fn op_add_do(self) -> OpAddDo<'buf> {
872 let mut res = OpAddDo::new(self);
873 res.request
874 .do_writeback(res.protocol(), "op-add-do", OpAddDo::lookup);
875 res
876 }
877 #[doc = "Delete port.\n\nFlags: admin-perm\n\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\n"]
878 pub fn op_del_do(self) -> OpDelDo<'buf> {
879 let mut res = OpDelDo::new(self);
880 res.request
881 .do_writeback(res.protocol(), "op-del-do", OpDelDo::lookup);
882 res
883 }
884 #[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\n"]
885 pub fn op_get_dump(self) -> OpGetDump<'buf> {
886 let mut res = OpGetDump::new(self);
887 res.request
888 .do_writeback(res.protocol(), "op-get-dump", OpGetDump::lookup);
889 res
890 }
891 #[doc = "Get tunnel info.\n\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\n"]
892 pub fn op_get_do(self) -> OpGetDo<'buf> {
893 let mut res = OpGetDo::new(self);
894 res.request
895 .do_writeback(res.protocol(), "op-get-do", OpGetDo::lookup);
896 res
897 }
898}
899#[cfg(test)]
900mod generated_tests {
901 use super::*;
902 #[test]
903 fn tests() {
904 let _ = IterableFou::get_ifindex;
905 let _ = IterableFou::get_ipproto;
906 let _ = IterableFou::get_local_v4;
907 let _ = IterableFou::get_local_v6;
908 let _ = IterableFou::get_peer_port;
909 let _ = IterableFou::get_peer_v4;
910 let _ = IterableFou::get_peer_v6;
911 let _ = IterableFou::get_port;
912 let _ = IterableFou::get_remcsum_nopartial;
913 let _ = IterableFou::get_type;
914 let _ = PushFou::<&mut Vec<u8>>::push_af;
915 let _ = PushFou::<&mut Vec<u8>>::push_ifindex;
916 let _ = PushFou::<&mut Vec<u8>>::push_ipproto;
917 let _ = PushFou::<&mut Vec<u8>>::push_local_v4;
918 let _ = PushFou::<&mut Vec<u8>>::push_local_v6;
919 let _ = PushFou::<&mut Vec<u8>>::push_peer_port;
920 let _ = PushFou::<&mut Vec<u8>>::push_peer_v4;
921 let _ = PushFou::<&mut Vec<u8>>::push_peer_v6;
922 let _ = PushFou::<&mut Vec<u8>>::push_port;
923 let _ = PushFou::<&mut Vec<u8>>::push_remcsum_nopartial;
924 let _ = PushFou::<&mut Vec<u8>>::push_type;
925 }
926}