# Advanced Mode - Implementation Summary

## Overview

The **advanced** mode is a unified network configuration mode that consolidates and extends the functionality of the previous `bridged` and `routed-multi-service` modes into a single, flexible interface.

## Design Rationale

### Problems with Old Approach

1. **Mode Fragmentation**: Separate modes for bridged and routed scenarios
2. **Limited Flexibility**: Couldn't mix bridges and routed interfaces
3. **Confusing Naming**: "bridged" mode actually supported standalone interfaces too
4. **Parameter Proliferation**: routed-multi-service had 6+ parameters for just 3 services
5. **No Scalability**: Adding new services required new parameters

### New Unified Approach

The advanced mode uses a **declarative, array-based configuration**:

```
interface_names:  wan,    iptv,           mgmt
interface_types:  route:vlan:100, bridge:tagged:200, direct:vlan:300
ports:       WAN,    LAN1-LAN2-WAN,  WAN
```

**Benefits**:
- ✅ Single mode for all scenarios
- ✅ Scalable (add N interfaces without new parameters)
- ✅ Flexible (mix bridge/route/standalone)
- ✅ Intuitive syntax
- ✅ Self-documenting configuration

## Architecture

### File Structure

```
netmode/
├── files/
│   ├── etc/netmodes/advanced/
│   │   └── scripts/
│   │       └── 10-advanced           # Main mode script
│   ├── lib/netmode/
│   │   └── advanced_helper.sh        # Helper library
│   └── etc/netmodes/supported_modes.json
└── docs/
    ├── ADVANCED_MODE_GUIDE.md         # Complete guide
    └── ADVANCED_MODE_QUICK_REFERENCE.md
```

### Components

#### 1. advanced_helper.sh

**Purpose**: Core library for interface creation

**Key Functions**:
- `parse_interface_type()` - Parse interface type specifications
- `create_bridge()` - Create bridge interfaces with VLAN/QinQ
- `create_routed_interface()` - Create routed interfaces with VLAN/MACVLAN
- `create_standalone_interface()` - Create direct VLAN interfaces
- `parse_port_list()` - Resolve port macros to device names
- `resolve_device_name()` - Resolve LAN1/WAN to actual device names
- `cleanup_interfaces()` - Clean up all interfaces before applying new config

#### 2. 10-advanced Script

**Purpose**: Main mode script

**Flow**:
1. Parse environment variables (NETMODE_*)
2. Split comma-separated values
3. Loop through each interface
4. Parse interface type
5. Call appropriate creation function (bridge/route/direct)
6. Configure multicast, DHCP, firewall
7. Update service dependencies

#### 3. supported_modes.json

**Purpose**: Mode definition for UCI import

**Configuration**:
```json
{
  "name": "advanced",
  "description": "Advanced Mode - Unified configuration...",
  "supported_args": [
    {
      "name": "interface_names",
      "description": "Interface names (comma-separated...)",
      "type": "string"
    },
    ...
  ]
}
```

## Interface Type Syntax

### Design Philosophy

**Format**: `MODE:SUBTYPE[:PARAMS][:MODIFIERS]`

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:vlan:2501-n` - Mode=direct, Param=VID, Modifier=proto_none

### Parsing Logic

The `parse_interface_type()` function:

1. **Extract modifiers** (-n, -d)
2. **Parse mode prefix** (bridge:/route:/direct:)
3. **Parse subtype** (transparent/tagged/vlan/macvlan)
4. **Parse parameters** (VID, SVID, MAC address)
5. **Export to environment variables** for caller

## UCI Device Resolution

### Problem

Port macros (LAN1, LAN2, WAN) are logical names that need to be mapped to actual hardware interfaces.

### Solution

```bash
resolve_device_name() {
    local device_id="$1"
    local resolved_name=""

    # Try UCI device section
    resolved_name="$(uci -q get network.${device_id}.name)"

    # Fallback to input
    if [ -z "$resolved_name" ]; then
        resolved_name="$device_id"
    fi

    echo "$resolved_name"
}
```

**Example**:
```
LAN1 → uci get network.LAN1.name → eth1
WAN  → uci get network.WAN.name  → ae_wan
```

### Port List Resolution

The `parse_port_list()` function:

1. **Check for "ALL"** → Resolve all LAN1-8 + WAN
2. **Parse dash-separated** → LAN1-LAN2-WAN → resolve each
3. **Return space-separated** → "eth1 eth2 ae_wan"

## VLAN Device Creation

### 802.1Q (C-tag)

```bash
create_vlan_device "eth0" "100" "8021q"
```

Creates:
```
config device 'eth0__100'
    option type '8021q'
    option enabled '1'
    option vid '100'
    option ifname 'eth0'
    option name 'eth0.100'
```

### 802.1ad (S-tag)

```bash
create_vlan_device "eth0" "300" "8021ad"
```

Creates:
```
config device 'eth0__300'
    option type '8021ad'
    option enabled '1'
    option vid '300'
    option ifname 'eth0'
    option name 'eth0.300'
```

### QinQ (Double Tagging)

For `bridge:qinq:100:300`:

```bash
# Create S-tag first
svlan=$(create_vlan_device "eth0" "300" "8021ad")  # eth0.300

# Create C-tag on top of S-tag
cvlan=$(create_vlan_device "$svlan" "100" "8021q")  # eth0.300.100
```

Result: `eth0.300.100` (S-tag 300, C-tag 100)

## MACVLAN Device Creation

For `route:macvlan:AA:BB:CC:DD:EE:FF`:

```bash
create_macvlan_device "ae_wan" "AA:BB:CC:DD:EE:FF" "iptv"
```

Creates:
```
config device 'iptv_macvlan'
    option type 'macvlan'
    option enabled '1'
    option ifname 'ae_wan'
    option name 'iptv_macvlan'
    option macaddr 'AA:BB:CC:DD:EE:FF'
    option mode 'passthru'
```

## Bridge Creation

### Transparent Bridge

For `bridge:transparent` with `ports='ALL'`:

```bash
create_bridge "wan" "bridge:transparent" "ALL"
```

Creates:
```
config interface 'wan'
    option proto 'dhcp'
    option device 'br-wan'

config device 'br_wan'
    option name 'br-wan'
    option type 'bridge'
    option bridge_empty '1'
    list ports 'eth1'
    list ports 'eth2'
    list ports 'ae_wan'
```

### VLAN-Tagged Bridge

For `bridge:tagged:100` with `ports='ALL'`:

Creates VLAN devices on all ports first, then adds to bridge:
```
config device 'br_mgmt'
    option name 'br-mgmt'
    option type 'bridge'
    list ports 'eth1.100'
    list ports 'eth2.100'
    list ports 'ae_wan.100'
```

## Routed Interface Creation

For `route:vlan:100`:

```bash
create_routed_interface "wan" "vlan" "100" "" "dhcp" "ae_wan" "0"
```

Creates:
```
config device 'ae_wan__100'
    option type '8021q'
    option vid '100'
    option ifname 'ae_wan'
    option name 'ae_wan.100'

config interface 'wan'
    option proto 'dhcp'
    option device 'ae_wan.100'
```

## Firewall Logic

The advanced mode has **intelligent firewall handling**:

```bash
configure_firewall() {
    local has_routed=0

    # Check if ANY interface is routed
    for if_type in $interface_types; do
        if echo "$if_type" | grep -q "^route:"; then
            has_routed=1
            break
        fi
    done

    if [ "$has_routed" = "1" ]; then
        uci set firewall.globals.enabled="1"  # Enable for routed
    else
        uci set firewall.globals.enabled="0"  # Disable for bridge-only
    fi
}
```

**Logic**:
- If **any** interface is routed → Enable firewall
- If **all** interfaces are bridges → Disable firewall

## Environment Variable Flow

### Input (UCI → Environment)

```bash
# In netmode init script
export NETMODE_interface_names="wan,iptv,mgmt"
export NETMODE_interface_types="route:vlan:100,route:vlan:200,route:vlan:300"
export NETMODE_ports="WAN,WAN,WAN"
```

### Parsing (Script)

```bash
# In 10-advanced script
local interface_names="${NETMODE_interface_names:-wan}"
local interface_types="${NETMODE_interface_types:-bridge:transparent}"
local ports="${NETMODE_ports:-ALL}"

# Split by comma
IFS=','
for name in $interface_names; do
    names_arr="$names_arr $name"
done
```

### Output (UCI Network Config)

```
config interface 'wan'
    option proto 'dhcp'
    option device 'ae_wan.100'

config interface 'iptv'
    option proto 'dhcp'
    option device 'ae_wan.200'
...
```

## Cleanup Strategy

Before applying new configuration, all existing interfaces are cleaned up:

```bash
cleanup_interfaces() {
    # Delete VLAN devices (8021q and 8021ad)
    for vlandev_sec in $(uci show network | grep -E "\.type='(8021q|8021ad)'" ...); do
        uci delete "$vlandev_sec"
    done

    # Delete MACVLAN devices
    for macvlandev_sec in $(uci show network | grep "\.type='macvlan'" ...); do
        uci delete "$macvlandev_sec"
    done

    # Delete bridge devices
    for brdev_sec in $(uci show network | grep "\.type='bridge'" ...); do
        uci delete "$brdev_sec"
    done

    # Delete standard interfaces
    uci delete network.lan
    uci delete network.wan
    uci delete network.wan6
}
```

This ensures a clean slate for the new configuration.

## Migration Path

### From bridged Mode

**Before**:
```bash
mode='bridged'
interface_names='wan,lan100'
interface_types='transparent,tagged:100'
ports='ALL,LAN1-LAN2'
```

**After**:
```bash
mode='advanced'
interface_names='wan,lan100'
interface_types='bridge:transparent,bridge:tagged:100'
ports='ALL,LAN1-LAN2'
```

**Change**: Add `bridge:` prefix to types.

### From routed-multi-service Mode

**Before**:
```bash
mode='routed-multi-service'
inet_vlanid='100'
iptv_vlanid='200'
mgmt_vlanid='300'
```

**After**:
```bash
mode='advanced'
interface_names='wan,iptv,mgmt'
interface_types='route:vlan:100,route:vlan:200,route:vlan:300'
ports='WAN,WAN,WAN'
```

**Change**: Explicit interface names and unified syntax.

## Testing Approach

### Unit Testing

Test individual helper functions:

```bash
# Test device resolution
resolve_device_name "LAN1"  # Should return eth1

# Test port parsing
parse_port_list "LAN1-LAN2-WAN"  # Should return "eth1 eth2 ae_wan"

# Test type parsing
parse_interface_type "bridge:qinq:100:300-n"
# Should set: mode=bridge, vlan_type=qinq, cvid=100, svid=300, proto=none
```

### Integration Testing

Test complete scenarios:

```bash
# Test transparent bridge
uci set netmode.global.mode='advanced'
uci set netmode.@supported_args[0].value='wan'
uci set netmode.@supported_args[1].value='bridge:transparent'
uci set netmode.@supported_args[2].value='ALL'
uci commit netmode
service netmode restart

# Verify
brctl show | grep br-wan
```

### Validation

```bash
# Check UCI output
uci show network

# Check actual interfaces
ip addr show
brctl show
ip -d link show type vlan

# Check logs
logread | grep netmode-advanced
```

## Performance Considerations

### Comma Splitting Optimization

The script uses efficient IFS-based splitting:

```bash
local OLD_IFS="$IFS"
IFS=','
for name in $interface_names; do
    names_arr="$names_arr $name"
done
IFS="$OLD_IFS"
```

This is faster than using `cut` or `awk` in loops.

### UCI Batching

All UCI commands are batched, with a single `uci commit` at the end:

```bash
# Multiple uci set commands
uci set ...
uci set ...
uci set ...

# Single commit
uci commit network
```

### Logging

Logging is selective - info level for major steps, debug for details:

```bash
_log "Creating interface $idx/$total_interfaces"  # Info
logger -s -p user.debug -t "$_log_prefix" "Adding port: $port"  # Debug
```

## Security Considerations

### Input Validation

- VLANs IDs: 1-4094
- MAC addresses: Validated format
- Port names: Resolved through UCI (trusted source)

### Privilege Separation

- Script runs as root (required for network config)
- No user input directly executed
- Environment variables sanitized through UCI

## Future Enhancements

Possible future additions:

1. **Static IP support**: `route:vlan:100:static:192.168.1.1`
2. **Port roles**: `ports='LAN1(tagged),LAN2(untagged)'`
3. **Bridge STP**: `bridge:transparent:stp`
4. **IPv6 specific**: `route:vlan:100:ipv6`
5. **Validation**: Pre-flight checks for VLAN conflicts

## Backward Compatibility

**Status**: ⚠️ Breaking change by design

The old `bridged` and `routed-multi-service` modes are **replaced** by advanced mode. This is acceptable because:

1. This is the **first deployment** of advanced features
2. No existing production deployments use old syntax
3. Cleaner architecture without legacy baggage
4. Documentation focuses on new syntax only

## Summary

The advanced mode represents a significant architectural improvement:

- ✅ **Unified**: One mode for all scenarios
- ✅ **Scalable**: Array-based configuration
- ✅ **Flexible**: Mix bridges, routed, standalone
- ✅ **Intuitive**: Self-documenting syntax
- ✅ **Powerful**: VLAN, QinQ, MACVLAN support
- ✅ **Clean**: No backward compatibility burden

---

**Implementation Version**: 1.0
**Date**: 2024-12-12
**Status**: Production Ready
