mirror of
https://github.com/cirruslabs/softnet.git
synced 2026-10-01 12:32:05 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9c9671170 | ||
|
|
eed811747c |
-68
@@ -1,68 +0,0 @@
|
||||
use_compute_credits: true
|
||||
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-runner:tahoe
|
||||
|
||||
env:
|
||||
PATH: "$PATH:$HOME/.cargo/bin"
|
||||
|
||||
task:
|
||||
name: Lint
|
||||
install_rust_script: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
rustfmt_script: cargo fmt --check
|
||||
clippy_script: cargo clippy --all-targets --all-features -- -D warnings
|
||||
|
||||
task:
|
||||
alias: Test
|
||||
matrix:
|
||||
- name: Test on macOS Sequoia
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-runner:sequoia
|
||||
- name: Test on macOS Tahoe
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-runner:tahoe
|
||||
install_rust_script: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
test_script: cargo test
|
||||
|
||||
task:
|
||||
name: Release (Dry Run)
|
||||
only_if: $CIRRUS_TAG == ''
|
||||
depends_on:
|
||||
- Lint
|
||||
- Test
|
||||
install_rust_script: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
install_script: brew install go
|
||||
install_goreleaser_script: brew install --cask goreleaser/tap/goreleaser-pro
|
||||
build_script: goreleaser build --snapshot
|
||||
goreleaser_artifacts:
|
||||
path: "dist/**"
|
||||
|
||||
task:
|
||||
name: Release
|
||||
only_if: $CIRRUS_TAG != ''
|
||||
depends_on:
|
||||
- Lint
|
||||
- Test
|
||||
env:
|
||||
GITHUB_TOKEN: ENCRYPTED[!98ace8259c6024da912c14d5a3c5c6aac186890a8d4819fad78f3e0c41a4e0cd3a2537dd6e91493952fb056fa434be7c!]
|
||||
GORELEASER_KEY: ENCRYPTED[!9b80b6ef684ceaf40edd4c7af93014ee156c8aba7e6e5795f41c482729887b5c31f36b651491d790f1f668670888d9fd!]
|
||||
SENTRY_ORG: cirrus-labs
|
||||
SENTRY_PROJECT: persistent-workers
|
||||
SENTRY_AUTH_TOKEN: ENCRYPTED[!c16a5cf7da5f856b4bc2f21fe8cb7aa2a6c981f851c094ed4d3025fd02ea59a58a86cee8b193a69a1fc20fa217e56ac3!]
|
||||
install_rust_script: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
install_script: brew install go getsentry/tools/sentry-cli
|
||||
install_goreleaser_script: brew install --cask goreleaser/tap/goreleaser-pro
|
||||
release_script: goreleaser
|
||||
upload_sentry_debug_files_script:
|
||||
- cd target/aarch64-apple-darwin/release/
|
||||
# Generate and upload symbols
|
||||
- dsymutil softnet
|
||||
- sentry-cli debug-files upload -o $SENTRY_ORG -p $SENTRY_PROJECT softnet.dSYM/
|
||||
# Bundle and upload sources
|
||||
- sentry-cli debug-files bundle-sources softnet.dSYM/
|
||||
- sentry-cli debug-files upload -o $SENTRY_ORG -p $SENTRY_PROJECT softnet.src.zip
|
||||
create_sentry_release_script:
|
||||
- export SENTRY_RELEASE="softnet@$CIRRUS_TAG"
|
||||
- sentry-cli releases new $SENTRY_RELEASE
|
||||
- sentry-cli releases set-commits $SENTRY_RELEASE --auto
|
||||
- sentry-cli releases finalize $SENTRY_RELEASE
|
||||
@@ -0,0 +1,102 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- '*'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: macos-15
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install Rust
|
||||
run: rustup toolchain install nightly --profile minimal --component rustfmt --component clippy
|
||||
- name: Check formatting
|
||||
run: cargo fmt --check
|
||||
- name: Clippy
|
||||
run: cargo clippy --all-targets --all-features -- -D warnings
|
||||
|
||||
test:
|
||||
name: Test on ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: macOS Sequoia
|
||||
runner: macos-15
|
||||
- name: macOS Tahoe
|
||||
runner: macos-26
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install Rust
|
||||
run: rustup toolchain install nightly --profile minimal
|
||||
- name: Test
|
||||
run: cargo test
|
||||
|
||||
release_dry_run:
|
||||
name: Release (Dry Run)
|
||||
if: github.event_name != 'pull_request' && github.ref_type != 'tag'
|
||||
needs:
|
||||
- lint
|
||||
- test
|
||||
runs-on: macos-15
|
||||
timeout-minutes: 45
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Rust
|
||||
run: rustup toolchain install nightly --profile minimal
|
||||
- name: Install tools
|
||||
run: |
|
||||
brew install go
|
||||
brew install --cask goreleaser/tap/goreleaser-pro
|
||||
- name: Build snapshot
|
||||
run: goreleaser build --snapshot
|
||||
- name: Upload dist
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: dist-dry-run
|
||||
path: dist/**
|
||||
if-no-files-found: ignore
|
||||
|
||||
release:
|
||||
name: Release
|
||||
if: github.ref_type == 'tag'
|
||||
needs:
|
||||
- lint
|
||||
- test
|
||||
runs-on: macos-15
|
||||
timeout-minutes: 45
|
||||
permissions:
|
||||
contents: write
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Rust
|
||||
run: rustup toolchain install nightly --profile minimal
|
||||
- name: Install tools
|
||||
run: |
|
||||
brew install go
|
||||
brew install --cask goreleaser/tap/goreleaser-pro
|
||||
- name: Release
|
||||
run: goreleaser
|
||||
Generated
-49
@@ -1333,15 +1333,6 @@ version = "2.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
|
||||
|
||||
[[package]]
|
||||
name = "ipnetwork"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iri-string"
|
||||
version = "0.7.10"
|
||||
@@ -1612,12 +1603,6 @@ dependencies = [
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "no-std-net"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65"
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.2.0"
|
||||
@@ -1822,38 +1807,6 @@ version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||
|
||||
[[package]]
|
||||
name = "pnet_base"
|
||||
version = "0.35.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffc190d4067df16af3aba49b3b74c469e611cad6314676eaf1157f31aa0fb2f7"
|
||||
dependencies = [
|
||||
"no-std-net",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pnet_datalink"
|
||||
version = "0.35.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e79e70ec0be163102a332e1d2d5586d362ad76b01cec86f830241f2b6452a7b7"
|
||||
dependencies = [
|
||||
"ipnetwork",
|
||||
"libc",
|
||||
"pnet_base",
|
||||
"pnet_sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pnet_sys"
|
||||
version = "0.35.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d4643d3d4db6b08741050c2f3afa9a892c4244c085a72fcda93c9c2c9a00f4b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "3.11.0"
|
||||
@@ -2615,14 +2568,12 @@ dependencies = [
|
||||
"dhcproto",
|
||||
"ip_network",
|
||||
"ipnet",
|
||||
"ipnetwork",
|
||||
"libc",
|
||||
"log",
|
||||
"mac_address",
|
||||
"nix 0.31.2",
|
||||
"num_enum 0.7.6",
|
||||
"oslog",
|
||||
"pnet_datalink",
|
||||
"polling",
|
||||
"prefix-trie",
|
||||
"privdrop",
|
||||
|
||||
@@ -34,8 +34,6 @@ oslog = "0.2.0"
|
||||
log = "0.4.29"
|
||||
serial_test = "3"
|
||||
coarsetime = "0.1.37"
|
||||
pnet_datalink = "0.35.0"
|
||||
ipnetwork = "0.20"
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
||||
+2
-36
@@ -1,7 +1,6 @@
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use clap::ValueEnum;
|
||||
use log::info;
|
||||
use smoltcp::wire::EthernetAddress;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::os::unix::net::UnixDatagram;
|
||||
@@ -29,17 +28,14 @@ pub struct Host {
|
||||
new_packets_rx: UnixDatagram,
|
||||
callback_can_continue_tx: SyncSender<()>,
|
||||
pub gateway_ip: smoltcp::wire::Ipv4Address,
|
||||
pub gateway_mac: Option<EthernetAddress>,
|
||||
pub max_packet_size: u64,
|
||||
pub read_max_packets: u64,
|
||||
finalized: bool,
|
||||
}
|
||||
|
||||
impl Host {
|
||||
pub fn new(vm_net_type: NetType, zero_cidr_allowed: bool, has_peers: bool) -> Result<Host> {
|
||||
// Initialize vmnet.framework's NAT or Host interface
|
||||
let enable_isolation = !zero_cidr_allowed && !has_peers;
|
||||
|
||||
pub fn new(vm_net_type: NetType, enable_isolation: bool) -> Result<Host> {
|
||||
// Initialize a vmnet.framework NAT or Host interface with isolation enabled
|
||||
let mut interface = vmnet::Interface::new(
|
||||
match vm_net_type {
|
||||
NetType::Nat => Mode::Shared(Default::default()),
|
||||
@@ -63,35 +59,6 @@ impl Host {
|
||||
let gateway_ip = Ipv4Addr::from_str(&gateway_ip)
|
||||
.context("failed to parse vmnet's interface start address")?;
|
||||
|
||||
// Determine gateway's MAC address in case we have any peers
|
||||
let mut gateway_mac: Option<EthernetAddress> = None;
|
||||
|
||||
if has_peers {
|
||||
for iface in pnet_datalink::interfaces() {
|
||||
if !iface.ips.iter().any(|ip| ip.ip() == gateway_ip) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if gateway_mac.is_some() {
|
||||
return Err(anyhow!(
|
||||
"cannot enforce peers: multiple host interfaces have vmnet gateway IP {}",
|
||||
gateway_ip
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(iface_mac) = iface.mac {
|
||||
gateway_mac = Some(EthernetAddress(iface_mac.octets()));
|
||||
}
|
||||
}
|
||||
|
||||
if gateway_mac.is_none() {
|
||||
return Err(anyhow!(
|
||||
"cannot enforce peers: no host interface has vmnet gateway IP {}",
|
||||
gateway_ip
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve max packet size for this interface
|
||||
let Some(Parameter::MaxPacketSize(max_packet_size)) =
|
||||
interface.parameters().get(ParameterKind::MaxPacketSize)
|
||||
@@ -138,7 +105,6 @@ impl Host {
|
||||
new_packets_rx,
|
||||
callback_can_continue_tx,
|
||||
gateway_ip,
|
||||
gateway_mac,
|
||||
max_packet_size,
|
||||
read_max_packets,
|
||||
finalized: false,
|
||||
|
||||
+6
-45
@@ -10,6 +10,12 @@ impl Proxy<'_> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Snoop bootpd(8) replies from the host to
|
||||
// figure out the IP assigned to the VM
|
||||
if frame.dst_addr() == self.vm_mac_address {
|
||||
self.snoop(frame);
|
||||
}
|
||||
|
||||
match self.vm.write(frame.as_ref()) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
@@ -31,51 +37,6 @@ impl Proxy<'_> {
|
||||
}
|
||||
|
||||
fn allowed_from_host(&mut self, frame: &EthernetFrame<&[u8]>) -> Option<()> {
|
||||
if self.peer_mac_addresses.is_empty() {
|
||||
// Peers unset → isolation between VMs is enabled → all frames are from gateway
|
||||
return self.allowed_from_gateway(frame);
|
||||
}
|
||||
|
||||
// Peers set → isolation between VMs is disabled → can receive a frame from any VM
|
||||
let from_gateway = Some(frame.src_addr()) == self.host.gateway_mac;
|
||||
if from_gateway {
|
||||
return self.allowed_from_gateway(frame);
|
||||
}
|
||||
|
||||
let from_peer = self.peer_mac_addresses.contains(&frame.src_addr());
|
||||
if from_peer {
|
||||
return self.allowed_from_peer(frame);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn allowed_from_gateway(&mut self, frame: &EthernetFrame<&[u8]>) -> Option<()> {
|
||||
let decision = match frame.ethertype() {
|
||||
EthernetProtocol::Arp => Some(()),
|
||||
EthernetProtocol::Ipv4 => Some(()),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if decision.is_some() {
|
||||
// Snoop bootpd(8) replies from the gateway to
|
||||
// figure out the IP assigned to the VM
|
||||
if frame.dst_addr() == self.vm_mac_address {
|
||||
self.snoop(frame);
|
||||
}
|
||||
}
|
||||
|
||||
decision
|
||||
}
|
||||
|
||||
fn allowed_from_peer(&mut self, frame: &EthernetFrame<&[u8]>) -> Option<()> {
|
||||
if frame.dst_addr() != self.vm_mac_address
|
||||
&& !frame.dst_addr().is_broadcast()
|
||||
&& !frame.dst_addr().is_multicast()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
match frame.ethertype() {
|
||||
EthernetProtocol::Arp => Some(()),
|
||||
EthernetProtocol::Ipv4 => Some(()),
|
||||
|
||||
+3
-27
@@ -15,9 +15,7 @@ use ipnet::Ipv4Net;
|
||||
use mac_address::MacAddress;
|
||||
use port_forwarder::PortForwarder;
|
||||
use prefix_trie::{Prefix, PrefixMap};
|
||||
use smoltcp::wire::EthernetAddress;
|
||||
use smoltcp::wire::EthernetFrame;
|
||||
use std::collections::HashSet;
|
||||
use std::io::ErrorKind;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::str::FromStr;
|
||||
@@ -29,7 +27,6 @@ pub struct Proxy<'proxy> {
|
||||
host: Host,
|
||||
poller: Poller<'proxy>,
|
||||
vm_mac_address: smoltcp::wire::EthernetAddress,
|
||||
peer_mac_addresses: HashSet<EthernetAddress>,
|
||||
dhcp_snooper: DhcpSnooper,
|
||||
rules: PrefixMap<Ipv4Net, Action>,
|
||||
enobufs_encountered: bool,
|
||||
@@ -54,23 +51,6 @@ impl FromStr for Target {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Peer {
|
||||
mac_address: EthernetAddress,
|
||||
}
|
||||
|
||||
impl FromStr for Peer {
|
||||
type Err = mac_address::MacParseError;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
let mac_address = MacAddress::from_str(s)?;
|
||||
|
||||
Ok(Peer {
|
||||
mac_address: EthernetAddress(mac_address.bytes()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub(crate) enum Action {
|
||||
Block,
|
||||
@@ -84,14 +64,12 @@ impl Proxy<'_> {
|
||||
vm_net_type: NetType,
|
||||
allow: Vec<Target>,
|
||||
block: Vec<Target>,
|
||||
peers: Vec<Peer>,
|
||||
exposed_ports: Vec<ExposedPort>,
|
||||
) -> Result<Proxy<'proxy>> {
|
||||
let vm = VM::new(vm_fd)?;
|
||||
let host = Host::new(
|
||||
vm_net_type,
|
||||
allow.contains(&Target::Prefix(Ipv4Net::zero())),
|
||||
!peers.is_empty(),
|
||||
!allow.contains(&Target::Prefix(Ipv4Net::zero())),
|
||||
)?;
|
||||
let poller_timeout = Duration::from_millis(100);
|
||||
let poller = Poller::new(vm.as_raw_fd(), host.as_raw_fd(), poller_timeout)?;
|
||||
@@ -125,7 +103,6 @@ impl Proxy<'_> {
|
||||
host,
|
||||
poller,
|
||||
vm_mac_address: smoltcp::wire::EthernetAddress(vm_mac_address.bytes()),
|
||||
peer_mac_addresses: peers.into_iter().map(|peer| peer.mac_address).collect(),
|
||||
dhcp_snooper: DhcpSnooper::new(poller_timeout),
|
||||
rules,
|
||||
enobufs_encountered: false,
|
||||
@@ -232,7 +209,7 @@ mod tests {
|
||||
use nix::sys::socket::{AddressFamily, SockFlag, SockType, socketpair};
|
||||
use prefix_trie::PrefixMap;
|
||||
use serial_test::serial;
|
||||
use smoltcp::wire::{EthernetAddress, Ipv4Address, Ipv4Packet};
|
||||
use smoltcp::wire::{Ipv4Address, Ipv4Packet};
|
||||
use std::collections::HashSet;
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::str::FromStr;
|
||||
@@ -318,7 +295,6 @@ mod tests {
|
||||
.map(|cidr| cidr.parse().unwrap())
|
||||
.collect(),
|
||||
Vec::default(),
|
||||
Vec::default(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -340,6 +316,6 @@ mod tests {
|
||||
|
||||
let ipv4_pkt = Ipv4Packet::new_unchecked(buf.as_slice());
|
||||
|
||||
proxy.allowed_from_vm_ipv4(ipv4_pkt, EthernetAddress([0; 6]))
|
||||
proxy.allowed_from_vm_ipv4(ipv4_pkt)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-28
@@ -4,7 +4,7 @@ use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use ipnet::Ipv4Net;
|
||||
use smoltcp::wire::{
|
||||
ArpPacket, EthernetAddress, EthernetFrame, EthernetProtocol, IpProtocol, Ipv4Packet, UdpPacket,
|
||||
ArpPacket, EthernetFrame, EthernetProtocol, IpProtocol, Ipv4Packet, UdpPacket,
|
||||
};
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
@@ -26,22 +26,6 @@ impl Proxy<'_> {
|
||||
return None;
|
||||
}
|
||||
|
||||
// When peers are set the isolation between VMs is disabled,
|
||||
// so we need to be stricter about what we'll emit
|
||||
if !self.peer_mac_addresses.is_empty() {
|
||||
// Destination check
|
||||
let to_gateway = Some(frame.dst_addr()) == self.host.gateway_mac;
|
||||
let to_peer = self.peer_mac_addresses.contains(&frame.dst_addr());
|
||||
|
||||
if !to_gateway
|
||||
&& !to_peer
|
||||
&& !frame.dst_addr().is_broadcast()
|
||||
&& !frame.dst_addr().is_multicast()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
match frame.ethertype() {
|
||||
EthernetProtocol::Arp => {
|
||||
let arp_pkt = ArpPacket::new_checked(frame.payload()).ok()?;
|
||||
@@ -49,7 +33,7 @@ impl Proxy<'_> {
|
||||
}
|
||||
EthernetProtocol::Ipv4 => {
|
||||
let ipv4_pkt = Ipv4Packet::new_checked(frame.payload()).ok()?;
|
||||
self.allowed_from_vm_ipv4(ipv4_pkt, frame.dst_addr())
|
||||
self.allowed_from_vm_ipv4(ipv4_pkt)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
@@ -74,22 +58,13 @@ impl Proxy<'_> {
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn allowed_from_vm_ipv4(
|
||||
&self,
|
||||
ipv4_pkt: Ipv4Packet<&[u8]>,
|
||||
dst_mac: EthernetAddress,
|
||||
) -> Option<()> {
|
||||
pub(crate) fn allowed_from_vm_ipv4(&self, ipv4_pkt: Ipv4Packet<&[u8]>) -> Option<()> {
|
||||
// Is this packet coming from VM's IP address that we've learned from DHCP snooping?
|
||||
if let Some(lease) = &self.dhcp_snooper.lease()
|
||||
&& lease.valid_ip_source(ipv4_pkt.src_addr())
|
||||
{
|
||||
let dst_addr = ipv4_pkt.dst_addr();
|
||||
|
||||
// Communication with peers bypasses IP rules
|
||||
if self.peer_mac_addresses.contains(&dst_mac) {
|
||||
return Some(());
|
||||
}
|
||||
|
||||
// Filter traffic based on user-specified rules first
|
||||
if !self.rules.is_empty() {
|
||||
let dst_net = Ipv4Net::from(dst_addr);
|
||||
|
||||
-12
@@ -6,7 +6,6 @@ use oslog::OsLogger;
|
||||
use privdrop::PrivDrop;
|
||||
use softnet::NetType;
|
||||
use softnet::proxy::ExposedPort;
|
||||
use softnet::proxy::Peer;
|
||||
use softnet::proxy::Proxy;
|
||||
use softnet::proxy::Target;
|
||||
use std::borrow::Cow;
|
||||
@@ -81,16 +80,6 @@ struct Args {
|
||||
)]
|
||||
block: Vec<Target>,
|
||||
|
||||
#[clap(
|
||||
long = "peer",
|
||||
help = "Comma-separated list of MAC addresses of the peer VMs to allow the traffic to \
|
||||
(e.g. --peer=AA:BB:CC:DD:EE:FF)",
|
||||
value_name = "comma-separated MAC addresses",
|
||||
use_value_delimiter = true,
|
||||
action = clap::ArgAction::Set
|
||||
)]
|
||||
peers: Vec<Peer>,
|
||||
|
||||
#[clap(
|
||||
long,
|
||||
help = "comma-separated list of TCP ports to expose (e.g. --expose 2222:22,8080:80)",
|
||||
@@ -212,7 +201,6 @@ fn try_main() -> anyhow::Result<()> {
|
||||
args.vm_net_type,
|
||||
args.allow,
|
||||
args.block,
|
||||
args.peers,
|
||||
args.expose,
|
||||
)
|
||||
.context("failed to initialize proxy")?;
|
||||
|
||||
Reference in New Issue
Block a user