From a37b91dc37d36312c750f39c9b487098290744b0 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 15 Nov 2024 20:36:56 -0500 Subject: [PATCH] v1 of virtualrouter definition schema --- .../virtual_network/router_server/config.rs | 197 ++++++++++---- .../router_server/default_config.yml | 243 ++++++++++++++++-- 2 files changed, 372 insertions(+), 68 deletions(-) diff --git a/veilid-tools/src/virtual_network/router_server/config.rs b/veilid-tools/src/virtual_network/router_server/config.rs index db748730..a0d71807 100644 --- a/veilid-tools/src/virtual_network/router_server/config.rs +++ b/veilid-tools/src/virtual_network/router_server/config.rs @@ -37,14 +37,54 @@ const fn default_weight() -> f32 { 1.0f32 } +#[derive(Debug, Clone, Deserialize)] +#[serde(untagged)] +pub enum WeightedList { + List { + #[serde(flatten)] + value: Vec>, + }, + Single { + #[serde(flatten)] + value: T, + }, +} + +#[derive(Debug, Clone, Default, Deserialize)] +pub struct Probability { + #[serde(flatten)] + probability: f32, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(untagged)] +pub enum Weighted { + Weighted { + item: T, + weight: f32, + }, + Unweighted { + #[serde(flatten)] + value: T, + }, +} + #[derive(Debug, Clone, Deserialize)] pub struct Profile { - machine: One, + instances: Vec, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(untagged)] +pub enum Instance { + Machine { machine: WeightedList }, + Template { template: WeightedList }, } #[derive(Debug, Clone, Deserialize)] pub struct Machine { - network: One, + #[serde(flatten)] + location: Location, #[serde(default)] address4: Option, #[serde(default)] @@ -55,57 +95,100 @@ pub struct Machine { bootstrap: bool, } -#[derive(Debug, Clone, Default, Deserialize)] -pub struct One { +#[derive(Debug, Clone, Deserialize)] +pub struct Template { #[serde(flatten)] - pub value: Vec>, -} - -#[derive(Debug, Clone, Default, Deserialize)] -pub struct OneOrNone { + location: Location, #[serde(flatten)] - pub value: Vec>, - #[serde(default = "default_weight")] - pub none_weight: f32, -} - -#[derive(Debug, Clone, Default, Deserialize)] -pub struct Probability { - #[serde(flatten)] - probability: f32, + limits: Limits, + #[serde(default)] + disable_capabilities: Vec, } #[derive(Debug, Clone, Deserialize)] -pub struct Weighted { - #[serde(flatten)] - pub value: T, - #[serde(default = "default_weight")] - pub weight: f32, +pub struct Limits { + machine_count: WeightedList, } +#[derive(Debug, Clone, Deserialize)] +#[serde(untagged)] +pub enum Location { + Network { network: WeightedList }, + Blueprint { blueprint: WeightedList }, +} + +//////////////////////////////////////////////////////////////// + #[derive(Debug, Clone, Deserialize)] pub struct Network { - #[serde(flatten)] - subnets: Subnets, + model: String, #[serde(default)] - distance: Option, - #[serde(flatten)] - performance: Performance, + ipv4: Option, #[serde(default)] - gateway: Option, + ipv6: Option, } +#[derive(Debug, Clone, Deserialize)] +pub struct NetworkIpv4 { + allocation: String, + #[serde(default)] + gateway: Option, +} +#[derive(Debug, Clone, Deserialize)] +pub struct NetworkIpv6 { + allocation: String, + #[serde(default)] + gateway: Option, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct NetworkGateway { + translation: Translation, + upnp: bool, + network: Option, +} + +//////////////////////////////////////////////////////////////// + +#[derive(Debug, Clone, Deserialize)] +pub struct Blueprint { + models: WeightedList, + #[serde(default)] + ipv4: Option, + #[serde(default)] + ipv6: Option, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct BlueprintIpv4 { + #[serde(default)] + allocation: Option, + prefix: u8, + #[serde(default)] + gateway: Option, +} +#[derive(Debug, Clone, Deserialize)] +pub struct BlueprintIpv6 { + #[serde(default)] + allocation: Option, + prefix: u8, + #[serde(default)] + gateway: Option, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct BlueprintGateway { + translation: WeightedList, + upnp: Probability, + network: Option, +} + +//////////////////////////////////////////////////////////////// + #[derive(Debug, Clone, Deserialize)] pub struct Subnets { - subnet4: OneOrNone, - subnet6: OneOrNone, -} - -#[derive(Debug, Clone, Deserialize)] -pub struct Gateway { - translation: One, - upnp: Probability, - network: String, + subnet4: Vec, + subnet6: Vec, } #[derive(Debug, Clone, Deserialize)] @@ -124,17 +207,7 @@ pub struct Distribution { } #[derive(Debug, Clone, Deserialize)] -pub struct Decay { - lambda: f32, -} - -#[derive(Debug, Clone, Deserialize)] -pub struct Performance { - latency: Distribution, - loss: Probability, -} - -#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "snake_case")] pub enum Translation { None, PortRestricted, @@ -142,12 +215,38 @@ pub enum Translation { Symmetric, } +impl Default for Translation { + fn default() -> Self { + Self::None + } +} + +#[derive(Debug, Clone, Deserialize)] +pub struct Model { + latency: Distribution, + #[serde(default)] + distance: Option, + #[serde(default)] + loss: Probability, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct Allocation { + #[serde(flatten)] + subnets: Subnets, +} + #[derive(Debug, Clone, Deserialize)] pub struct Config { seed: Option, + default_network: String, profiles: HashMap, machines: HashMap, + templates: HashMap, networks: HashMap, + blueprint: HashMap, + allocations: HashMap, + models: HashMap, } impl Config { diff --git a/veilid-tools/src/virtual_network/router_server/default_config.yml b/veilid-tools/src/virtual_network/router_server/default_config.yml index cd312876..148dcc24 100644 --- a/veilid-tools/src/virtual_network/router_server/default_config.yml +++ b/veilid-tools/src/virtual_network/router_server/default_config.yml @@ -1,9 +1,46 @@ --- +# Random number seed used to generate all profile configurations +# for a test. The seed can be overriden on the VirtualRouter command +# line to choose a different test scenario. The same seed will +# generate the same configuration on all machines given the same +# configuration file. seed: 0 + +# The name of the predefined network to use by default (typically +# this is '$internet') +default_network: "$internet" + +################################################################# +# Profiles +# +# Profiles are ordered lists of machine instances or machine templates +# to assign to new instances of Veilid as they are allocated from +# the VirtualRouter + profiles: - - default: - bootstrap: + instances: + # two bootstrap machines + - machine: "bootstrap-1.veilid.net" + - machine: "bootstrap-2.veilid.net" + # pool of up to 4 relay-capable servers + - template: "bootrelay" + # geographically disperse servers of various configurations - server: + instances: + - template: + - "relayserver" + - "ipv4server" + - "ipv6server" + - "nat4home" + - "nat4+6home" + +################################################################# +# Machines +# +# Machines are single, fully-defined machine specifications that +# can only be allocated one time + machines: - bootstrap-1.veilid.net: network: "boot" @@ -19,25 +56,193 @@ machines: disable_capabilities: ["ROUT", "TUNL", "SGNL", "RLAY", "DIAL", "DHTV", "DHTW", "APPM"] bootstrap: true + +################################################################# +# Templates +# +# Templates are used to generate Machines that are all on a single +# network. A maximum number of machines are allocated on the +# network within the limits specified. + +templates: + # Default servers on the boot network + # - will have ipv4 and ipv6 addresses + # - will have no capabilities disabled + # - will not use NAT, and be directly connected + # - limited to 4 machines + - bootrelay: + network: "boot" + machine_count: 4 + # Servers on subnets within the 'internet' network + - relayserver: + blueprint: "direct" + machine_count: [1, 2, 3] + - ipv4server: + blueprint: "direct_ipv4_no_ipv6" + machine_count: [1, 2, 3] + - ipv6server: + blueprint: "direct_ipv6_no_ipv4" + machine_count: [1, 2, 3] + - nat4home: + blueprint: "nat_ipv4_no_ipv6" + machine_count: [1, 2, 3] + - nat4+6home: + blueprint: "nat_ipv4_direct_ipv6" + machine_count: [1, 2, 3] + +################################################################# +# Networks +# +# Networks are + networks: - - internet: - distance: - min: 0.04 - max: 2.0 - latency: - mean: 0.200 - sigma: 0.080 - skew: 0 - min: 0.030 - max: 0.400 - loss: 0.01 + # Custom networks + - boot: + model: "$lan" + ipv4: + allocation: "boot" + ipv6: + allocation: "boot" + + # Predefined networks + - $internet: + model: "$internet" + +################################################################# +# Blueprints +# +# Blueprints are used to generate Networks for use with Machines + +blueprints: + # A subnet of the internet directly attached with no translation + # with both ipv4 and ipv6 networking + - direct: + models: "$lan" + ipv4: + prefix: 24 + ipv6: + prefix: 64 + # An ipv4-only subnet of the internet directly attached with no translation + - direct_ipv4_no_ipv6: + models: "$lan" + ipv4: + prefix: 24 + # An ipv6-only subnet of the internet directly attached with no translation + - direct_ipv6_no_ipv4: + models: "$lan" + ipv6: + prefix: 64 + # An ipv4-only subnet of the internet attached via NAT + - nat_ipv4_no_ipv6: + models: "$lan" + ipv4: + allocation: "$private" + prefix: 0 + gateway: + translation: "PortRestricted" + upnp: 0.25 + # An ipv4 subnet of the internet attached via NAT and + # an ipv6 subnet of the internet directly attached with no translation + - nat_ipv4_direct_ipv6: + models: "$lan" + ipv4: + allocation: "$private" + prefix: 0 + gateway: + translation: "PortRestricted" + upnp: 0.25 + ipv6: + prefix: 56 + +################################################################# +# Allocations +# +# Allocations are partitions of the address space that networks +# can be assigned to. Machines on the networks will be given +# addresses within these ranges. If an allocation +# is not specified, an address -outside- any of the allocation +# will be used (on the 'public internet'). + +allocations: + # Custom network allocations - boot: subnet4: ["170.64.128.0/24"] subnet6: ["2a03:b0c0:2::/48"] - latency: - mean: 0.0038 - sigma: 0.001416 - skew: 0.0009 - min: 0.0015 - max: 0.0075 - loss: 0.0 + + # Predefined networks + - $private: + subnet4: ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"] + subnet6: ["fc00::/7"] + - $cgnat: + subnet4: ["100.64.0.0/10"] + - $linklocal: + subnet4: ["169.254.0.0/16"] + subnet6: ["fe80::/10"] + - $localhost: + subnet4: ["127.0.0.0/8"] + subnet6: ["::1/128"] + - $ietf: + subnet4: ["192.0.0.0/24"] + - $cellnat: + subnet4: ["192.0.0.0/29"] + - $documentation: + subnet4: ["192.0.2.0/24", "198.51.100.0/24", "203.0.113.0/24"] + subnet6: ["2001:db8::/32", "3fff::/20"] + - $benchmark: + subnet4: ["198.18.0.0/15"] + - $mulitcast: + subnet4: ["224.0.0.0/4"] + - $mulitcasttest: + subnet4: ["233.252.0.0/24"] + subnet6: ["ff00::/8"] + - $unspecified: + subnet4: ["0.0.0.0/8"] + subnet6: ["::/128"] + - $reserved: + subnet4: ["192.88.99.0/24", "240.0.0.0/4"] + - $broadcast: + subnet4: ["255.255.255.255/32"] + - $mapped: + subnet6: ["::ffff:0:0/96", "::ffff:0:0:0/96"] + - $translation: + subnet6: ["64:ff9b::/96", "64:ff9b:1::/48"] + - $discard: + subnet6: ["100::/64"] + - $teredo: + subnet6: ["2001::/32"] + - $orchidv2: + subnet6: ["2001:20::/28"] + - $6to4: + subnet6: ["2002::/16"] + - $srv6: + subnet6: ["5f00::/16"] + +################################################################# +# Models +# +# Performance models representing how a network behaves +# Latency models are a skewed normal distribution +# Distance is assigned over a circular probability and then +# mapped linearly as a multiplier to latency and loss + +models: + # Predefined models + $lan: + latency: + mean: 0.0038 + sigma: 0.001416 + skew: 0.0009 + min: 0.0015 + max: 0.0075 + loss: 0.0 + $internet: + distance: + min: 0.04 + max: 2.0 + latency: + mean: 0.200 + sigma: 0.080 + skew: 0 + min: 0.030 + max: 0.400 + loss: 0.01