Skip to content

Commit 982e9a6

Browse files
authored
fix(interfaces): assign default metric for WANs (#1441)
1 parent 56e7010 commit 982e9a6

File tree

3 files changed

+40
-5
lines changed

3 files changed

+40
-5
lines changed

packages/ns-api/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5195,7 +5195,8 @@ All parameters:
51955195
- `dhcp_client_id`: Client ID to send when requesting DHCP
51965196
- `dhcp_vendor_class`: Vendor class to send when requesting DHCP
51975197
- `dhcp_hostname_to_send`: Hostname to send when requesting DHCP, can be `deviceHostname`, `doNotSendHostname` or `customHostname`
5198-
- `dhcp_custom_hostname`: Custom hostname to use when `dhcp_hostname_to_send = customHostname`
5198+
- `dhcp_custom_hostname`: Custom hostname to use when `dhcp_hostname_to_send = customHostname
5199+
- `metric`: Routing metric for the interface, if left empty, system will assign an incremental value
51995200
52005201
```bash
52015202
api-cli ns.devices configure-device --data '{"device_type": "physical", "interface_name": "myiface", "protocol": "static", "zone": "lan", "ip6_enabled": false, "device_name": "eth2", "ip4_address": "10.20.30.40/24"}'

packages/ns-api/files/misc/wireguard-migrate.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,26 @@ def fix_addresses():
6161
fixed_addresses.append(address)
6262
else:
6363
fixed_addresses.append(address)
64-
e_uci.set("network", wg_id, "addresses", fixed_addresses)
64+
if fixed_addresses != list(addresses):
65+
e_uci.set("network", wg_id, "addresses", fixed_addresses)
6566

6667
e_uci.save("network")
6768

6869

70+
def add_metric_to_wans():
71+
"""
72+
Add metric to WAN interfaces if missing. This fixes https://github.com/NethServer/nethsecurity/issues/1428.
73+
This logic has been borrowed from https://github.com/NethServer/python3-nethsec/blob/ab7bfb757d602bdbba5aeb2b6e53ef0f3a36d02b/src/nethsec/mwan/__init__.py#L64.
74+
"""
75+
e_uci = EUci()
76+
for network in e_uci.get('firewall', 'ns_wan', 'network', dtype=str, default=[], list=True):
77+
if e_uci.get('network', network, 'metric', default=None) is None:
78+
e_uci.set('network', network, 'metric', 20)
79+
80+
e_uci.save('network')
81+
82+
6983
if __name__ == "__main__":
7084
migrate_old()
7185
fix_addresses()
86+
add_metric_to_wans()

packages/ns-api/files/ns.devices

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ def get_bonding_values(ip4_addr_cidr, attached_devices, bonding_policy, bond_pri
610610
return values
611611

612612

613-
def set_network_configuration(device_type, interface_name, logical_type, interface_to_edit, protocol, zone, ip4_addr_cidr, ip4_gateway, ip6_enabled, ip6_address, ip6_gateway, attached_devices, bonding_policy, bond_primary_device, pppoe_username, pppoe_password, dhcp_client_id, dhcp_vendor_class, dhcp_hostname_to_send, dhcp_custom_hostname, uci):
613+
def set_network_configuration(device_type, interface_name, logical_type, interface_to_edit, protocol, zone, ip4_addr_cidr, ip4_gateway, ip6_enabled, ip6_address, ip6_gateway, attached_devices, bonding_policy, bond_primary_device, pppoe_username, pppoe_password, dhcp_client_id, dhcp_vendor_class, dhcp_hostname_to_send, dhcp_custom_hostname, uci, metric: int = None):
614614
if device_type == 'logical' and logical_type == 'bond':
615615
values = get_bonding_values(
616616
ip4_addr_cidr, attached_devices, bonding_policy, bond_primary_device)
@@ -697,9 +697,26 @@ def set_network_configuration(device_type, interface_name, logical_type, interfa
697697
if interface_to_edit and delete_dhcp_hostname:
698698
uci.delete('network', interface_name, 'hostname')
699699

700-
# disable "force link" on red interfaces
701700
if zone == 'wan':
701+
# disable "force link" on red interfaces
702702
values['force_link'] = '0'
703+
# assign metric if missing
704+
if metric is not None:
705+
values["metric"] = metric
706+
else:
707+
metrics = set()
708+
for network in uci.get("firewall", "ns_wan", "network", dtype=str, default=[], list=True):
709+
metric = uci.get("network", network, "metric", default=None, dtype=int)
710+
if metric is not None:
711+
metrics.add(metric)
712+
713+
base_metric = 20
714+
while base_metric in metrics:
715+
base_metric += 10
716+
values["metric"] = base_metric
717+
else:
718+
# remove metric if interface changes zone
719+
values['metric'] = ''
703720

704721
for key, value in values.items():
705722
uci.set('network', interface_name, key, value)
@@ -833,6 +850,7 @@ def configure_device(input_data):
833850
dhcp_vendor_class = input_data.get('dhcp_vendor_class')
834851
dhcp_hostname_to_send = input_data.get('dhcp_hostname_to_send')
835852
dhcp_custom_hostname = input_data.get('dhcp_custom_hostname')
853+
metric = input_data.get('metric')
836854
bridge_device_name = ''
837855

838856
# validate input data
@@ -848,7 +866,7 @@ def configure_device(input_data):
848866
device_name, device_type, interface_name, protocol, logical_type, bridge_device_name, uci)
849867

850868
set_network_configuration(device_type, interface_name, logical_type, interface_to_edit, protocol, zone, ip4_address, ip4_gateway, ip6_enabled, ip6_address, ip6_gateway,
851-
attached_devices, bonding_policy, bond_primary_device, pppoe_username, pppoe_password, dhcp_client_id, dhcp_vendor_class, dhcp_hostname_to_send, dhcp_custom_hostname, uci)
869+
attached_devices, bonding_policy, bond_primary_device, pppoe_username, pppoe_password, dhcp_client_id, dhcp_vendor_class, dhcp_hostname_to_send, dhcp_custom_hostname, uci, metric)
852870

853871
set_firewall_zone(interface_name, zone, interface_to_edit, uci)
854872

@@ -1180,6 +1198,7 @@ if cmd == 'list':
11801198
'dhcp_vendor_class': 'string',
11811199
'dhcp_hostname_to_send': 'string',
11821200
'dhcp_custom_hostname': 'string',
1201+
'metric': 'integer'
11831202
},
11841203
'unconfigure-device': {
11851204
'iface_name': 'string',

0 commit comments

Comments
 (0)