From 40240a7152ac0360e7db8b6d022a27a5d2c64a8b Mon Sep 17 00:00:00 2001 From: Mohd Husaam Mehdi Date: Thu, 22 Jan 2026 16:11:20 +0530 Subject: [PATCH] netmode: update handling of direct interfaces the idea is to make them similar to route interface, to avoid confusion * they can be also be mgmt/inet/iptv * they will have default proto set to dhcp * syntax is now direct:vlan:100 or direct:transparent --- netmode/docs/ADVANCED_MODE_GUIDE.md | 18 ++++---- netmode/docs/ADVANCED_MODE_IMPLEMENTATION.md | 4 +- netmode/docs/ADVANCED_MODE_QUICK_REFERENCE.md | 5 +- netmode/docs/CONFIGURATION_SCENARIOS.md | 8 ++-- netmode/docs/USER_GUIDE.md | 4 +- netmode/docs/VALIDATION_AND_ERROR_HANDLING.md | 2 +- .../etc/netmodes/advanced/scripts/10-advanced | 9 ++-- netmode/files/lib/netmode/advanced_helper.sh | 46 ++++++++++++------- 8 files changed, 55 insertions(+), 41 deletions(-) diff --git a/netmode/docs/ADVANCED_MODE_GUIDE.md b/netmode/docs/ADVANCED_MODE_GUIDE.md index 1bc4abcfa..66517b079 100644 --- a/netmode/docs/ADVANCED_MODE_GUIDE.md +++ b/netmode/docs/ADVANCED_MODE_GUIDE.md @@ -17,7 +17,7 @@ The **advanced** mode is a unified, flexible network configuration mode for Open - **Bridge interfaces** with VLAN/QinQ support (traditional VLAN devices) - **Bridge VLAN filtering** (modern kernel bridge features - recommended) - **Routed interfaces** with VLAN/MACVLAN support -- **Standalone interfaces** (direct VLAN without bridge) +- **Standalone interfaces** (direct VLAN without bridge, similar to Routed, but does not support macvlan, or inet or iptv modifiers (those require routing), but it can be set to mgmt). - **Mixed scenarios** (combine bridges and routed interfaces) ### Key Features @@ -37,7 +37,7 @@ The **advanced** mode is a unified, flexible network configuration mode for Open | Parameter | Description | Example | |-----------|-------------|---------| | `interface_names` | Comma-separated interface names | `wan,iptv,mgmt` | -| `interface_types` | Comma-separated interface types | `bridge:transparent,brvlan:wan-tagged:1499,route:vlan:100,direct:200` | +| `interface_types` | Comma-separated interface types | `bridge:transparent,brvlan:wan-tagged:1499,route:vlan:100,direct:vlan:200` | | `ports` | Comma-separated port assignments | `ALL,LAN1-LAN2-WAN,WAN` | | `macaddrs` | Comma-separated MAC addresses (optional) | `BaseMACAddress,BaseMACAddressP1,AA:BB:CC:DD:EE:FF` | @@ -93,11 +93,11 @@ Routed types create L3 routed interfaces (with NAT/firewall). ### Standalone Types -Standalone types create VLAN interfaces without bridges or routing (proto=none by default). +Standalone types create VLAN interfaces without bridges or routing (proto=dhcp by default). | Type | Syntax | Description | |------|--------|-------------| -| **Direct VLAN** | `direct:VID` | Standalone VLAN interface, proto=none | +| **Direct VLAN** | `direct:vlan:VID` | Standalone VLAN interface, proto=dhcp | ### Device Reference Types @@ -143,10 +143,12 @@ Modifiers can be appended to any interface type: #### Notes +- For each interface individually, if more than one modifier is present, ordering among the modifiers should be as follows: none (or n), static, dhcp, dhcpv6, pppoe, mgmt, inet, iptv, d. Example: `uci set netmode.@supported_args[13].value='bridge:transparent-n,direct:vlan:100-dhcp-mgmt'` +- Some modifiers are mutually exclusive, for example mgmt and inet. - The `-none` and `-n` modifiers are equivalent, as are `-disabled` and `-d`. - If no protocol modifier is specified, interfaces default to `proto=dhcp`. - Protocols and disabled can be clubbed together, and disabled should be in the last, for example: `transparent-qinq:2-n-d` will set proto as none and disable the interface, similarly other protocols can be used. -- iptv, inet and mgmt modifier can only be used with route interfaces, and they can be clubbed with disabled modifier, but disable should be in the last. +- iptv and inet modifier can only be used with route interfaces, mgmt can be used with route or direct interfaces, and they can be clubbed with disabled modifier, but disable should be in the last. #### Static IP Auto-Configuration @@ -176,7 +178,7 @@ ports='ALL_LAN,WAN' For non-LAN interfaces with `-static`, only `proto=static` is set without additional configuration. -**Note**: Direct interfaces default to `proto=none`, so `-n` is implicit. +**Note**: Direct interfaces default to `proto=dhcp`. ### MAC Address Assignment @@ -388,13 +390,13 @@ service netmode restart ```bash uci set netmode.global.mode='advanced' uci set netmode.@supported_args[12].value='wan' -uci set netmode.@supported_args[13].value='direct:2501' +uci set netmode.@supported_args[13].value='direct:vlan:2501' uci set netmode.@supported_args[14].value='WAN' uci commit netmode service netmode restart ``` -**Result**: Creates WAN.2501 interface, proto=none (no DHCP) +**Result**: Creates WAN.2501 interface, proto=DHCP --- diff --git a/netmode/docs/ADVANCED_MODE_IMPLEMENTATION.md b/netmode/docs/ADVANCED_MODE_IMPLEMENTATION.md index 16b940fff..ffcc28aef 100644 --- a/netmode/docs/ADVANCED_MODE_IMPLEMENTATION.md +++ b/netmode/docs/ADVANCED_MODE_IMPLEMENTATION.md @@ -20,7 +20,7 @@ The advanced mode uses a **declarative, array-based configuration**: ``` interface_names: wan, iptv, mgmt -interface_types: route:vlan:100, bridge:tagged:200, direct:300 +interface_types: route:vlan:100, bridge:tagged:200, direct:vlan:300 ports: WAN, LAN1-LAN2-WAN, WAN ``` @@ -107,7 +107,7 @@ Examples: - `bridge:transparent` - Mode=bridge, Subtype=transparent - `bridge:tagged:100` - Mode=bridge, Subtype=tagged, Param=VID - `route:vlan:100:AA:BB:CC:DD:EE:FF` - Mode=route, Subtype=vlan, Params=VID+MAC -- `direct:2501-n` - Mode=direct, Param=VID, Modifier=proto_none +- `direct:vlan:2501-n` - Mode=direct, Param=VID, Modifier=proto_none ### Parsing Logic diff --git a/netmode/docs/ADVANCED_MODE_QUICK_REFERENCE.md b/netmode/docs/ADVANCED_MODE_QUICK_REFERENCE.md index 1c567d6e4..b35d70af0 100644 --- a/netmode/docs/ADVANCED_MODE_QUICK_REFERENCE.md +++ b/netmode/docs/ADVANCED_MODE_QUICK_REFERENCE.md @@ -30,7 +30,8 @@ route:vlan:VID:MAC # VLAN + custom MAC ### Standalone Types ``` -direct:VID # Standalone VLAN (proto=none) +direct:vlan:VID # Standalone VLAN (proto=dhcp) +direct:transparent # No VLAN ``` ### Device Reference Types @@ -150,7 +151,7 @@ uci commit netmode && service netmode restart ```bash uci set netmode.global.mode='advanced' uci set netmode.@supported_args[0].value='wan' -uci set netmode.@supported_args[1].value='direct:2501' +uci set netmode.@supported_args[1].value='direct:vlan:2501' uci set netmode.@supported_args[2].value='WAN' uci commit netmode && service netmode restart ``` diff --git a/netmode/docs/CONFIGURATION_SCENARIOS.md b/netmode/docs/CONFIGURATION_SCENARIOS.md index 72fffebd6..14bf6c62b 100644 --- a/netmode/docs/CONFIGURATION_SCENARIOS.md +++ b/netmode/docs/CONFIGURATION_SCENARIOS.md @@ -594,7 +594,7 @@ uci commit netmode && service netmode restart **Network Topology**: ``` -WAN.2501 → wan (standalone, proto=none) +WAN.2501 → wan (standalone, proto=dhcp) ``` ### UCI Configuration @@ -602,7 +602,7 @@ WAN.2501 → wan (standalone, proto=none) ```bash uci set netmode.global.mode='advanced' uci set netmode.mode_4_supprted_args_1.value='wan' -uci set netmode.mode_4_supprted_args_2.value='direct:2501' +uci set netmode.mode_4_supprted_args_2.value='direct:vlan:2501' uci set netmode.mode_4_supprted_args_3.value='WAN' uci commit netmode && service netmode restart ``` @@ -622,7 +622,7 @@ uci commit netmode && service netmode restart Device.X_IOWRT_EU_NetMode.SupportedModes.4.SupportedArguments.2.Value - direct:2501 + direct:vlan:2501 Device.X_IOWRT_EU_NetMode.SupportedModes.4.SupportedArguments.3.Value @@ -705,7 +705,7 @@ uci commit netmode && service netmode restart | QinQ Bridge | `bridge:qinq:CVID:SVID` | Wholesale provider, double tagging | | Routed VLAN | `route:vlan:VID` | Need routing/NAT per service | | Routed MACVLAN | `route:macvlan:MAC` | Different MAC per service | -| Direct VLAN | `direct:VID` | Standalone VLAN for custom protocols | +| Direct VLAN | `direct:vlan:VID` | Standalone VLAN for custom protocols | ### Modifiers diff --git a/netmode/docs/USER_GUIDE.md b/netmode/docs/USER_GUIDE.md index 8b38c03c2..e10ee2e1e 100644 --- a/netmode/docs/USER_GUIDE.md +++ b/netmode/docs/USER_GUIDE.md @@ -257,7 +257,7 @@ service netmode restart **Configuration Parameters**: - `interface_names` (optional): Comma-separated interface names (default: wan) -- `interface_types` (optional): Comma-separated types (transparent, tagged:VID, direct:VID, qinq:C:S, etc.) +- `interface_types` (optional): Comma-separated types (transparent, tagged:VID, direct:vlan:VID, qinq:C:S, etc.) - `ports` (optional): Comma-separated port lists (default: ALL) **Basic Configuration**: @@ -281,7 +281,7 @@ service netmode restart # Standalone VLAN interface (no bridge) uci set netmode.global.mode='bridged' uci set netmode.@supported_args[0].value='wan' -uci set netmode.@supported_args[1].value='direct:2501' # Direct VLAN interface +uci set netmode.@supported_args[1].value='direct:vlan:2501' # Direct VLAN interface uci set netmode.@supported_args[2].value='WAN' uci commit netmode service netmode restart diff --git a/netmode/docs/VALIDATION_AND_ERROR_HANDLING.md b/netmode/docs/VALIDATION_AND_ERROR_HANDLING.md index f7ed0487f..c01725742 100644 --- a/netmode/docs/VALIDATION_AND_ERROR_HANDLING.md +++ b/netmode/docs/VALIDATION_AND_ERROR_HANDLING.md @@ -76,7 +76,7 @@ ERROR: Invalid port identifier in 'LAN1-LAN9-WAN': 'LAN9' **Example Errors**: ``` ERROR: Unknown interface type: 'bridge:unknown:100' -Valid types: bridge:transparent, bridge:tagged:VID, brvlan:wan-tagged:VID, route:vlan:VID, route:macvlan:MAC, direct:VID +Valid types: bridge:transparent, bridge:tagged:VID, brvlan:wan-tagged:VID, route:vlan:VID, route:macvlan:MAC, direct:vlan:VID, direct:transparent ERROR: VLAN ID in type 'route:vlan:9999' out of range (must be 1-4094): 9999 ``` diff --git a/netmode/files/etc/netmodes/advanced/scripts/10-advanced b/netmode/files/etc/netmodes/advanced/scripts/10-advanced index 20c75ff38..38e42f9f4 100755 --- a/netmode/files/etc/netmodes/advanced/scripts/10-advanced +++ b/netmode/files/etc/netmodes/advanced/scripts/10-advanced @@ -196,7 +196,7 @@ configure_interfaces() { MGMT_IFACES="$MGMT_IFACES $if_name" fi - if [ "$vlan_type" = "macvlan" ] && [ "$mac_count" -gt 0 ]; then + if [ "$vlan_type" = "macvlan" ] || [ "$mac_count" -gt 0 ]; then MACVLAN_PRESENT=1 fi @@ -269,8 +269,7 @@ configure_interfaces() { base_device=$(echo "$actual_ports" | awk '{print $1}') fi - create_standalone_interface "$if_name" "$cvid" "$proto" "$base_device" "$disabled" "$if_mac" - ;; + create_standalone_interface "$if_name" "$vlan_type" "$cvid" "$if_mac" "$proto" "$base_device" "$disabled" ;; esac idx=$((idx + 1)) @@ -482,14 +481,14 @@ configure_dhcp() { configure_firewall() { _log "Configuring firewall" - # Check if any interface is routed + # Check if any interface is routed | direct local interface_types="${NETMODE_interface_types:-bridge:transparent}" local has_routed=0 local OLD_IFS="$IFS" IFS=',' for if_type in $interface_types; do - if echo "$if_type" | grep -q "^route:"; then + if echo "$if_type" | grep -qE "route|direct"; then has_routed=1 break fi diff --git a/netmode/files/lib/netmode/advanced_helper.sh b/netmode/files/lib/netmode/advanced_helper.sh index bed9c50ed..24222321f 100644 --- a/netmode/files/lib/netmode/advanced_helper.sh +++ b/netmode/files/lib/netmode/advanced_helper.sh @@ -148,7 +148,7 @@ validate_interface_type() { # Validate based on type case "$base_type" in - bridge:transparent|route:transparent) + bridge:transparent|route:transparent|direct:transparent) return 0 ;; device-ref:*) @@ -195,8 +195,8 @@ validate_interface_type() { local mac="${base_type#route:macvlan:}" validate_mac_address "$mac" "1" || return 1 ;; - direct:*) - local vid="${base_type#direct:}" + direct:vlan:*) + local vid="${base_type#direct:vlan:}" validate_vlan_id "$vid" "VLAN ID in type '$type_spec'" || return 1 ;; *) @@ -569,7 +569,7 @@ parse_port_list() { } # Parse advanced interface type specification -# Format: bridge:TYPE or route:TYPE or direct:VID or brvlan:TYPE (bridge VLAN filtering) +# Format: bridge:TYPE or route:TYPE or direct:vlan:VID or brvlan:TYPE (bridge VLAN filtering) # Returns: mode, vlan_type, cvid, svid, mac_addr, proto, disabled parse_interface_type() { local type_spec="$1" @@ -583,7 +583,6 @@ parse_interface_type() { local _purpose="" # mgmt, inet (internet) or iptv # Check for modifiers (must be at the end of the string) - # Process -disabled and -d (both set disabled flag) if echo "$type_spec" | grep -qE -- '-(disabled|d)$'; then _disabled="1" @@ -593,7 +592,7 @@ parse_interface_type() { # route interfaces can have different purposes, which will # affect firewall and mcast uci - if echo "$type_spec" | grep -qE -- 'route'; then + if echo "$type_spec" | grep -qE -- 'route|direct'; then if echo "$type_spec" | grep -qE -- '-iptv$'; then _purpose="iptv" type_spec="${type_spec%-iptv}" @@ -728,11 +727,15 @@ parse_interface_type() { ;; # Direct (standalone) mode - direct:*) + direct:vlan:*) _mode="direct" _vlan_type="vlan" - _cvid="${type_spec#direct:}" - [ "$_proto" != "none" ] && _proto="none" # Direct defaults to none + _cvid="${type_spec#direct:vlan:}" + ;; + + direct:transparent) + _mode="direct" + _vlan_type="none" ;; *) @@ -984,18 +987,27 @@ create_bridge_vlan_filtering() { # Create standalone interface (no bridge, direct VLAN device) create_standalone_interface() { local if_name="$1" - local vlan_id="$2" - local proto="$3" - local base_device="$4" - local disabled="$5" - local mac_addr="$6" + local vlan_type="$2" + local vlan_id="$3" + local mac_addr="$4" + local proto="$5" + local base_device="$6" + local disabled="$7" local _log_prefix="netmode-advanced" - logger -s -p user.info -t "$_log_prefix" "Creating standalone interface: $if_name, VLAN: $vlan_id, device: $base_device, mac: $mac_addr" + logger -s -p user.info -t "$_log_prefix" "Creating standalone interface: $if_name, type: $vlan_type, VLAN: $vlan_id, device: $base_device, mac: $mac_addr" - # Create VLAN device - local vlan_dev=$(create_vlan_device "$base_device" "$vlan_id" "8021q") + case "$vlan_type" in + vlan) + # Create VLAN device + vlan_dev=$(create_vlan_device "$base_device" "$vlan_id" "8021q") + ;; + none) + # Direct on base device + vlan_dev="$base_device" + ;; + esac # Create interface pointing directly to VLAN device (no bridge) uci -q delete "network.${if_name}"