1 // Copyright 2021 Ian Jackson and contributors to Hippotat
2 // SPDX-License-Identifier: GPL-3.0-or-later
3 // There is NO WARRANTY.
7 pub async fn run(global: Arc<Global>,
8 mut rx: mpsc::Receiver<RoutedPacket>,
9 mut ipif: Ipif) -> Result<Void,AE> {
11 let mut goodness: i32 = 0;
12 const GOODNESS_SHIFT: u8 = 8;
13 const GOODNESS_MIN: i32 = -16;
21 let data = data.ok_or_else(|| anyhow!("rx stream end!"))?;
22 let mut data = &*data.data;
23 let mut slip_end = &[SLIP_END][..];
24 let mut buf = Buf::chain(&mut data, &mut slip_end);
25 ipif.rx.write_all_buf(&mut buf).await
26 .context("write to ipif")?;
29 data = Ipif::next_frame(&mut ipif.tx) =>
32 let may_route = MayRoute::came_from_outside_hippotatd();
34 goodness -= goodness >> GOODNESS_SHIFT;
36 match process1(SlipNoConv, global.config.mtu, &data, |header|{
37 let saddr = ip_packet_addr::<false>(header)?;
38 let daddr = ip_packet_addr::<true>(header)?;
41 Err(PE::Empty) => { },
45 error!("[good={}] invalid data from local tx ipif {}",
47 if goodness < GOODNESS_MIN {
48 throw!(anyhow!("too many bad packets, too few good ones!"))
52 Ok((ref data, (ref saddr, ref daddr)))
53 if ! global.config.vnetwork.iter().any(|n| n.contains(saddr)) => {
54 // pretent as if this came from route
57 "discard to={:?} came=ipif user=local len={} outside-vnets: from={:?}",
58 daddr, saddr, data.len());
61 Ok((data, (_saddr, daddr))) => {
64 &global, "ipif", None,
65 data, daddr, may_route.clone()
74 ipif.quitting(None).await;