Skip to content

Commit d72eab8

Browse files
committed
feat(vsock): make subnet optional for Group scope IP filtering (#10)
When using scope 1 (Group) for IP filtering, subnet specification is now optional. If no subnet is provided, all connections will be blocked, matching scope 0 behavior. This provides more flexibility in network configuration while maintaining security. - Update IpFilterConfig to make subnet optional for scope 1 - Modify is_valid() to accept scope 1 without subnet - Update documentation in libkrun.h to clarify scope behaviors - Improve warning message specificity in VsockMuxer creation
1 parent add30f9 commit d72eab8

File tree

3 files changed

+15
-8
lines changed

3 files changed

+15
-8
lines changed

include/libkrun.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,12 @@ int32_t krun_set_port_map(uint32_t ctx_id, const char *const port_map[]);
371371
* "ctx_id" - the configuration context ID.
372372
* "c_ip" - an optional null-terminated string representing the guest's static IPv4 address.
373373
* "c_subnet" - an optional null-terminated string representing the guest's subnet in CIDR notation (e.g., "192.168.1.0/24").
374-
* "scope" - an integer specifying the scope (0-3). Refer to TSI documentation for details.
374+
* If scope is 1 and subnet is not provided, all connections will be blocked.
375+
* "scope" - an integer specifying the scope (0-3):
376+
* 0: None - Block all IP communication
377+
* 1: Group - Allow within subnet (if specified; otherwise, block all like scope 0)
378+
* 2: Public - Allow public IPs
379+
* 3: Any - Allow any IP
375380
*
376381
* Returns:
377382
* Zero on success or a negative error number on failure.

src/devices/src/virtio/vsock/ip_filter.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::net::Ipv4Addr;
1010
pub struct IpFilterConfig {
1111
/// Defines the scope of allowed connections/bindings.
1212
/// 0: None (Block all IP communication)
13-
/// 1: Group (Allow within `subnet`, bind only to `ip` if specified)
13+
/// 1: Group (Allow within `subnet` if specified, otherwise behaves like scope 0)
1414
/// 2: Public (Allow public IPs, bind only to `ip` if specified)
1515
/// 3: Any (Allow any IP, bind only to `ip` if specified)
1616
pub scope: u8,
@@ -19,7 +19,8 @@ pub struct IpFilterConfig {
1919
/// (ignored if scope is 0).
2020
pub ip: Option<Ipv4Addr>,
2121

22-
/// The allowed subnet for Scope 1 (Group). Required if scope is 1.
22+
/// The allowed subnet for Scope 1 (Group). Optional - if not provided when scope is 1,
23+
/// all connections will be blocked (same as scope 0).
2324
pub subnet: Option<Ipv4Network>,
2425
}
2526

@@ -31,9 +32,8 @@ impl IpFilterConfig {
3132
/// Checks if the configuration is logically valid.
3233
pub fn is_valid(&self) -> bool {
3334
match self.scope {
34-
0 | 2 | 3 => true, // Scopes 0, 2, 3 are valid without extra checks (ip is optional)
35-
1 => self.subnet.is_some(), // Scope 1 requires a subnet
36-
_ => false, // Invalid scope number
35+
0 | 1 | 2 | 3 => true, // All valid scopes (subnet is optional for scope 1)
36+
_ => false, // Invalid scope number
3737
}
3838
}
3939

@@ -57,13 +57,14 @@ impl IpFilterConfig {
5757
0 => false, // Scope 0: Deny all connections
5858
1 => {
5959
// Scope 1: Group - Allow connection only if dest_ip is within the specified subnet
60+
// If no subnet is specified, behaves like scope 0 (deny all)
6061
self.subnet.map_or(false, |subnet| subnet.contains(dest_ip))
6162
}
6263
2 => {
6364
// Scope 2: Public - Allow connection only if dest_ip is NOT private
6465
!Self::is_private(dest_ip)
6566
}
66-
3 => true, // Scope 3: Any - Allow connection to any IP
67+
3 => true, // Scope 3: Any - Allow connection to any IP
6768
_ => false, // Invalid scope
6869
}
6970
}
@@ -82,6 +83,7 @@ impl IpFilterConfig {
8283
// No specific IP specified, check based on scope rules for the bind_ip itself
8384
match self.scope {
8485
// Scope 1: Group - Allow binding within the subnet if no specific IP given
86+
// If no subnet is specified, behaves like scope 0 (deny all)
8587
1 => self.subnet.map_or(false, |subnet| subnet.contains(bind_ip)),
8688
// Scope 2: Public - Allow binding to public IPs if no specific IP given
8789
2 => !Self::is_private(bind_ip),

src/devices/src/virtio/vsock/muxer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ impl VsockMuxer {
127127
ip_filter: IpFilterConfig,
128128
) -> Self {
129129
if !ip_filter.is_valid() {
130-
warn!("Invalid IpFilterConfig provided during VsockMuxer creation: {:?}. Check configuration.", ip_filter);
130+
warn!("Invalid IpFilterConfig provided during VsockMuxer creation: {:?}. Scope value must be between 0 and 3.", ip_filter);
131131
}
132132

133133
VsockMuxer {

0 commit comments

Comments
 (0)