2026-05-27 20:56:30 -04:00
{
"client_requirement" : "client_is_viewer+" ,
"items" : [
{
"type" : "header_page_title" ,
"items" : [
{
"type" : "h1" ,
"text" : "Network Layout"
} ,
{
"type" : "p" ,
"text" : "Network segments managed by systemd-networkd, dnsmasq, nftables, and freeradius."
}
]
} ,
{
"type" : "info_bar" ,
"variant" : "info" ,
"text" : "For a basic flat network with no VLAN segmentation, only use VLAN 1 and delete the others."
} ,
{
"type" : "table" ,
"datasource" : "config:vlans" ,
"empty_message" : "No VLANs configured." ,
"columns" : [
{
"label" : "VLAN ID" ,
"field" : "vlan_id" ,
"class" : "col-mono col-narrow"
} ,
{
"label" : "Name" ,
"field" : "name" ,
"class" : "col-narrow"
} ,
{
"label" : "Interface" ,
"field" : "interface" ,
"class" : "col-mono col-narrow"
} ,
{
"label" : "Subnet" ,
"field" : "subnet" ,
"class" : "col-mono col-narrow"
} ,
{
"label" : "Mask" ,
"field" : "subnet_mask" ,
"class" : "col-mono col-narrow"
} ,
{
"label" : "Self Ident(s)" ,
"field" : "server_identity_ips" ,
"render" : "tag_list"
} ,
{
"label" : "Blocklists" ,
"field" : "use_blocklists" ,
"class" : "col-expand" ,
"render" : "tag_list"
} ,
{
"label" : "Default" ,
"field" : "radius_default" ,
"class" : "col-narrow" ,
"render" : "badge_yes_no" ,
"render_options" : {
"title_true" : "RADIUS Default" ,
"title_false" : "Not RADIUS Default"
}
} ,
{
"label" : "mDNS" ,
"field" : "mdns_reflection" ,
"class" : "col-narrow" ,
"render" : "badge_yes_no" ,
"render_options" : {
"title_true" : "mDNS Reflection Enabled" ,
"title_false" : "mDNS Reflection Disabled"
}
} ,
{
"label" : "Record" ,
"field" : "dnsmasq_log_queries" ,
"class" : "col-narrow" ,
"render" : "badge_yes_no" ,
"render_options" : {
"title_true" : "DNS Queries Recorded" ,
"title_false" : "DNS Queries Not Recorded"
}
}
] ,
"row_actions" : [
{
"client_requirement" : "client_is_administrator+" ,
2026-05-27 22:04:04 -04:00
"action" : "/action/networklayout/vlans_edit" ,
2026-05-27 20:56:30 -04:00
"method" : "inline_edit" ,
"text" : "Edit" ,
"class" : "btn-ghost btn-sm" ,
"fields" : [
{
"col" : "name" ,
"input_type" : "text" ,
"validate" : "dashname"
} ,
{
"col" : "subnet" ,
"input_type" : "text" ,
"validate" : "subnet"
} ,
{
"col" : "subnet_mask" ,
"input_type" : "number" ,
"min" : 1 ,
"max" : 30
} ,
{
"col" : "server_identity_ips" ,
"input_type" : "textarea_pair" ,
"col_label" : "IP Address" ,
"pair_col" : "server_identity_descriptions" ,
"pair_label" : "Description (Opt)" ,
"pair_wide" : true ,
"pair_col2" : "server_identity_hostnames" ,
"pair_label2" : "Hostname (Opt)" ,
"gateway_col" : "server_identity_gateway" ,
"dns_col" : "server_identity_dns_server" ,
"ntp_col" : "server_identity_ntp_server"
} ,
{
"col" : "radius_default" ,
"input_type" : "checkbox" ,
"checkbox_label" : "Enabled"
} ,
{
"col" : "mdns_reflection" ,
"input_type" : "checkbox" ,
"checkbox_label" : "Enabled"
} ,
{
"col" : "dnsmasq_log_queries" ,
"input_type" : "checkbox" ,
"checkbox_label" : "Record"
} ,
{
"col" : "use_blocklists" ,
"input_type" : "checkbox_multi" ,
"options" : "%BLOCKLIST_NAME_OPTIONS%"
}
]
} ,
{
"client_requirement" : "client_is_administrator+" ,
2026-05-27 22:04:04 -04:00
"action" : "/action/networklayout/vlans_delete" ,
2026-05-27 20:56:30 -04:00
"method" : "post" ,
"text" : "Delete" ,
"class" : "btn-danger btn-sm" ,
"disable_if" : {
"field" : "vlan_id" ,
"value" : 1
}
}
]
} ,
{
"type" : "card" ,
"id" : "add-form" ,
"label" : "Add VLAN" ,
"client_requirement" : "client_is_administrator+" ,
"items" : [
{
"type" : "form" ,
2026-05-27 22:04:04 -04:00
"action" : "/action/networklayout/addvlan_add" ,
2026-05-27 20:56:30 -04:00
"method" : "post" ,
"items" : [
{
"type" : "field_row" ,
"cols" : 4 ,
"items" : [
{
"type" : "field" ,
"label" : "VLAN ID" ,
"name" : "vlan_id" ,
"input_type" : "number" ,
"min" : 1 ,
"max" : 4094 ,
"validate" : "vlan_id" ,
"hint" : "Unique integer 1-4094. Sets the 802.1Q tag and interface name."
} ,
{
"type" : "field" ,
"label" : "VLAN Name" ,
"name" : "name" ,
"input_type" : "text" ,
"validate" : "dashname" ,
"hint" : "Lowercase letters, digits, hyphens. E.g. iot"
} ,
{
"type" : "subnet_row" ,
2026-05-28 00:38:48 -04:00
"label" : "VLAN Subnet" ,
2026-05-27 20:56:30 -04:00
"subnet_name" : "subnet" ,
"prefix_name" : "subnet_mask" ,
"subnet_placeholder" : "e.g. 192.168.x.0" ,
"prefix_value" : "24"
} ,
{
"type" : "field" ,
"label" : "VLAN Type" ,
"name" : "is_vpn" ,
"input_type" : "checkbox" ,
"checkbox_label" : "Is VPN" ,
"hint" : "Check if this VLAN uses a WireGuard interface (e.g. wg0, wg1, etc)."
}
]
} ,
{
"type" : "hr"
} ,
2026-05-27 23:41:34 -04:00
{
"type" : "record_editor" ,
2026-05-28 00:38:48 -04:00
"label" : "Router identities on this VLAN" ,
2026-05-27 23:41:34 -04:00
"name" : "server_identities" ,
"empty_message" : "No identities added." ,
"fields" : [
{
"label" : "IP Address" ,
"name" : "ip" ,
"valtype" : "address" ,
"attrs" : {
"data-dep-subnet" : "[name='subnet']" ,
"data-dep-mask" : ".subnet-prefix-input"
} ,
"placeholder" : "x.x.x.x" ,
"required" : true
} ,
{
"label" : "Description" ,
"name" : "description" ,
"placeholder" : "Optional label"
} ,
{
"label" : "Hostname" ,
"name" : "hostname" ,
"validate" : "networkname" ,
"placeholder" : "Optional"
}
]
} ,
{
"type" : "hr"
} ,
2026-05-28 01:42:31 -04:00
{
"type" : "field_row" ,
"cols" : 4 ,
"items" : [
{
2026-05-28 01:57:36 -04:00
"type" : "readonly_select" ,
2026-05-28 01:42:31 -04:00
"label" : "Gateway" ,
"name" : "gateway"
} ,
{
2026-05-28 01:57:36 -04:00
"type" : "overridable_textarea" ,
2026-05-28 01:42:31 -04:00
"label" : "DNS Server(s)" ,
"name" : "dns_server" ,
2026-05-28 01:57:36 -04:00
"override_name" : "dns_server_override" ,
"validate" : "ip_in_subnet"
2026-05-28 01:42:31 -04:00
} ,
{
2026-05-28 01:57:36 -04:00
"type" : "overridable_textarea" ,
2026-05-28 01:42:31 -04:00
"label" : "NTP Server(s)" ,
"name" : "ntp_server" ,
2026-05-28 01:57:36 -04:00
"override_name" : "ntp_server_override" ,
"validate" : "ip_in_subnet"
2026-05-28 01:42:31 -04:00
} ,
{
"type" : "field" ,
"label" : "Domain" ,
"name" : "dhcp_domain" ,
"input_type" : "text" ,
"validate" : "networkname" ,
"value" : "local"
}
]
} ,
2026-05-28 00:25:19 -04:00
{
"type" : "hr"
} ,
2026-05-27 20:56:30 -04:00
{
"type" : "field" ,
"label" : "Blocklists" ,
"name" : "use_blocklists" ,
"input_type" : "checkbox_group" ,
"options" : "%BLOCKLIST_NAME_OPTIONS%" ,
"hint" : "Note: Selected lists will be merged and de-duplicated prior to use."
} ,
{
"type" : "hr"
} ,
{
2026-05-27 23:41:34 -04:00
"type" : "field" ,
"label" : "RADIUS Default" ,
"name" : "radius_default" ,
"input_type" : "checkbox" ,
"hint" : "Wireless devices without a DHCP reservation will be placed into this VLAN. (Note: wired devices are not placed via RADIUS but rather by layer 3 switch policy.)"
} ,
{
"type" : "field" ,
"label" : "mDNS Reflection" ,
"name" : "mdns_reflection" ,
"input_type" : "checkbox" ,
"hint" : "Reflect mDNS traffic to/from this VLAN via avahi-daemon. Not supported on WireGuard interfaces."
} ,
{
"type" : "field" ,
"label" : "Record DNS Queries" ,
"name" : "dnsmasq_log_queries" ,
"input_type" : "checkbox" ,
"hint" : "Log every DNS query. High volume - enable for debugging only."
2026-05-27 20:56:30 -04:00
} ,
{
"type" : "button_row" ,
"items" : [
{
"type" : "button_primary" ,
2026-05-27 22:04:04 -04:00
"action" : "/action/networklayout/addvlan_add" ,
2026-05-27 20:56:30 -04:00
"method" : "post" ,
"text" : "Add VLAN" ,
"class" : "add-vlan-btn" ,
"disabled" : true
} ,
{
"type" : "button_cancel" ,
"text" : "Cancel"
}
]
}
]
}
]
}
]
2026-05-28 00:38:48 -04:00
}