mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-06-03 10:50:20 +00:00
Github issue 314: static IP configuration enhancement
* fixed IP configuration * set up a new ipv4settings object to avoid the need of reseting all the values * extended Static IP configuration: * allow configuration of netmask (optional) * allow configuration of Gateway (optional) * allow configuartion of two DNS Servers (optional) * extend DHCP configuration: * allow configuration of user specific DNS Server * DHCP provided DNS Servers will be ignored in that case
This commit is contained in:
parent
b0e7a57668
commit
1a1faa8a1b
@ -59,6 +59,8 @@ available over this interfaces. Select Internal only for trusted networks.'),
|
||||
choices=[('external', 'External'), ('internal', 'Internal')])
|
||||
ipv4_method = forms.ChoiceField(
|
||||
label=_('IPv4 Addressing Method'),
|
||||
help_text='"Shared" will start a DHCP Server, "Automatic" will \
|
||||
start a DHCP client.',
|
||||
choices=[('auto', 'Automatic (DHCP)'),
|
||||
('shared', 'Shared'),
|
||||
('manual', 'Manual')])
|
||||
@ -66,6 +68,31 @@ available over this interfaces. Select Internal only for trusted networks.'),
|
||||
label=_('Address'),
|
||||
validators=[validators.validate_ipv4_address],
|
||||
required=False)
|
||||
ipv4_netmask = forms.CharField(
|
||||
label=_('Netmask'),
|
||||
help_text='Optional value. If not given the default netmask \
|
||||
(associated with the address) will be used',
|
||||
validators=[validators.validate_ipv4_address],
|
||||
required=False)
|
||||
ipv4_gateway = forms.CharField(
|
||||
label=_('Gateway'),
|
||||
help_text='Optional value.',
|
||||
validators=[validators.validate_ipv4_address],
|
||||
required=False)
|
||||
ipv4_dns = forms.CharField(
|
||||
label=_('DNS Server'),
|
||||
help_text='Optional value. If this value is given and IPv4 \
|
||||
Addressing Method is DHCP, the DNS Servers from DHCP Server \
|
||||
will be ignored.',
|
||||
validators=[validators.validate_ipv4_address],
|
||||
required=False)
|
||||
ipv4_second_dns = forms.CharField(
|
||||
label=_('Second DNS Server'),
|
||||
help_text='Optional value. If this value is given and IPv4 \
|
||||
Addressing Method is DHCP, the DNS Servers from DHCP Server \
|
||||
will be ignored.',
|
||||
validators=[validators.validate_ipv4_address],
|
||||
required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the form, populate interface choices."""
|
||||
@ -143,6 +170,27 @@ Point.'))
|
||||
label=_('Address'),
|
||||
validators=[validators.validate_ipv4_address],
|
||||
required=False)
|
||||
ipv4_netmask = forms.CharField(
|
||||
label=_('Netmask'),
|
||||
help_text='Optional value. If not given the default netmask \
|
||||
(associated with the address) will be used',
|
||||
validators=[validators.validate_ipv4_address],
|
||||
required=False)
|
||||
ipv4_gateway = forms.CharField(
|
||||
label=_('Gateway'),
|
||||
help_text='Optional value.',
|
||||
validators=[validators.validate_ipv4_address],
|
||||
required=False)
|
||||
ipv4_dns = forms.CharField(
|
||||
label=_('DNS Server'),
|
||||
help_text='Optional value.',
|
||||
validators=[validators.validate_ipv4_address],
|
||||
required=False)
|
||||
ipv4_second_dns = forms.CharField(
|
||||
label=_('Second DNS Server'),
|
||||
help_text='Optional value.',
|
||||
validators=[validators.validate_ipv4_address],
|
||||
required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the form, populate interface choices."""
|
||||
|
||||
@ -140,11 +140,16 @@ def edit(request, uuid):
|
||||
else:
|
||||
ipv4_method = form.cleaned_data['ipv4_method']
|
||||
ipv4_address = form.cleaned_data['ipv4_address']
|
||||
ipv4_netmask = form.cleaned_data['ipv4_netmask']
|
||||
ipv4_gateway = form.cleaned_data['ipv4_gateway']
|
||||
ipv4_dns = form.cleaned_data['ipv4_dns']
|
||||
ipv4_second_dns = form.cleaned_data['ipv4_second_dns']
|
||||
|
||||
if connection.get_connection_type() == '802-3-ethernet':
|
||||
network.edit_ethernet_connection(
|
||||
connection, name, interface, zone, ipv4_method,
|
||||
ipv4_address)
|
||||
ipv4_address, ipv4_netmask, ipv4_gateway,
|
||||
ipv4_dns, ipv4_second_dns)
|
||||
elif connection.get_connection_type() == '802-11-wireless':
|
||||
ssid = form.cleaned_data['ssid']
|
||||
mode = form.cleaned_data['mode']
|
||||
@ -153,7 +158,8 @@ def edit(request, uuid):
|
||||
|
||||
network.edit_wifi_connection(
|
||||
connection, name, interface, zone, ssid, mode, auth_mode,
|
||||
passphrase, ipv4_method, ipv4_address)
|
||||
passphrase, ipv4_method, ipv4_address, ipv4_netmask,
|
||||
ipv4_gateway, ipv4_dns, ipv4_second_dns)
|
||||
elif connection.get_connection_type() == 'pppoe':
|
||||
network.edit_pppoe_connection(
|
||||
connection, name, interface, zone, username, password)
|
||||
@ -176,8 +182,20 @@ def edit(request, uuid):
|
||||
settings_ipv4 = connection.get_setting_ip4_config()
|
||||
form_data['ipv4_method'] = settings_ipv4.get_method()
|
||||
address = network.get_first_ip_address_from_connection(connection)
|
||||
netmask = network.get_first_netmask_from_connection(connection)
|
||||
gateway = settings_ipv4.get_gateway()
|
||||
dns = settings_ipv4.get_dns(0)
|
||||
second_dns = settings_ipv4.get_dns(1)
|
||||
if address:
|
||||
form_data['ipv4_address'] = address
|
||||
if netmask:
|
||||
form_data['ipv4_netmask'] = netmask
|
||||
if gateway:
|
||||
form_data['ipv4_gateway'] = gateway
|
||||
if dns:
|
||||
form_data['ipv4_dns'] = dns
|
||||
if second_dns:
|
||||
form_data['ipv4_second_dns'] = second_dns
|
||||
|
||||
if settings_connection.get_connection_type() == '802-11-wireless':
|
||||
settings_wireless = connection.get_setting_wireless()
|
||||
@ -291,9 +309,14 @@ def add_ethernet(request):
|
||||
zone = form.cleaned_data['zone']
|
||||
ipv4_method = form.cleaned_data['ipv4_method']
|
||||
ipv4_address = form.cleaned_data['ipv4_address']
|
||||
ipv4_netmask = form.cleaned_data['ipv4_netmask']
|
||||
ipv4_gateway = form.cleaned_data['ipv4_gateway']
|
||||
ipv4_dns = form.cleaned_data['ipv4_dns']
|
||||
ipv4_second_dns = form.cleaned_data['ipv4_second_dns']
|
||||
|
||||
network.add_ethernet_connection(
|
||||
name, interface, zone, ipv4_method, ipv4_address)
|
||||
name, interface, zone, ipv4_method, ipv4_address, ipv4_netmask,
|
||||
ipv4_gateway, ipv4_dns, ipv4_second_dns)
|
||||
return redirect(reverse_lazy('networks:index'))
|
||||
else:
|
||||
form = AddEthernetForm()
|
||||
@ -356,10 +379,15 @@ def add_wifi(request, ssid=None, interface_name=None):
|
||||
passphrase = form.cleaned_data['passphrase']
|
||||
ipv4_method = form.cleaned_data['ipv4_method']
|
||||
ipv4_address = form.cleaned_data['ipv4_address']
|
||||
ipv4_netmask = form.cleaned_data['ipv4_netmask']
|
||||
ipv4_gateway = form.cleaned_data['ipv4_gateway']
|
||||
ipv4_dns = form.cleaned_data['ipv4_dns']
|
||||
ipv4_second_dns = form.cleaned_data['ipv4_second_dns']
|
||||
|
||||
network.add_wifi_connection(
|
||||
name, interface, zone, ssid, mode, auth_mode, passphrase,
|
||||
ipv4_method, ipv4_address)
|
||||
ipv4_method, ipv4_address, ipv4_netmask,
|
||||
ipv4_gateway, ipv4_dns, ipv4_second_dns)
|
||||
return redirect(reverse_lazy('networks:index'))
|
||||
else:
|
||||
if form_data:
|
||||
|
||||
@ -45,18 +45,26 @@
|
||||
|
||||
if ($("#id_ipv4_method").prop("value") != "manual") {
|
||||
$("#id_ipv4_address").prop("readOnly", true);
|
||||
$("#id_ipv4_netmask").prop("readOnly", true);
|
||||
$("#id_ipv4_gateway").prop("readOnly", true);
|
||||
}
|
||||
$("#id_name").focus();
|
||||
|
||||
$("#id_ipv4_method").change(function() {
|
||||
if ($("#id_ipv4_method").prop("value") == 'manual') {
|
||||
$("#id_ipv4_address").prop("readOnly", false);
|
||||
$("#id_ipv4_address").prop("required", true);
|
||||
} else {
|
||||
$("#id_ipv4_address").val("");
|
||||
$("#id_ipv4_address").prop("readOnly", true);
|
||||
$("#id_ipv4_address").prop("required", false);
|
||||
}
|
||||
if ($("#id_ipv4_method").prop("value") == "manual") {
|
||||
$("#id_ipv4_address").prop("readOnly", false);
|
||||
$("#id_ipv4_address").prop("required", true);
|
||||
$("#id_ipv4_netmask").prop("readOnly", false);
|
||||
$("#id_ipv4_gateway").prop("readOnly", false);
|
||||
} else {
|
||||
$("#id_ipv4_address").val("");
|
||||
$("#id_ipv4_address").prop("readOnly", true);
|
||||
$("#id_ipv4_address").prop("required", false);
|
||||
$("#id_ipv4_netmask").val("");
|
||||
$("#id_ipv4_netmask").prop("readOnly", true);
|
||||
$("#id_ipv4_gateway").val("");
|
||||
$("#id_ipv4_gateway").prop("readOnly", true);
|
||||
}
|
||||
});
|
||||
|
||||
$('#id_show_password').change(function() {
|
||||
|
||||
@ -45,6 +45,8 @@
|
||||
|
||||
if ($("#id_ipv4_method").prop("value") != "manual") {
|
||||
$("#id_ipv4_address").prop("readOnly", true);
|
||||
$("#id_ipv4_netmask").prop("readOnly", true);
|
||||
$("#id_ipv4_gateway").prop("readOnly", true);
|
||||
}
|
||||
$("#id_name").focus();
|
||||
|
||||
@ -52,10 +54,16 @@
|
||||
if ($("#id_ipv4_method").prop("value") == "manual") {
|
||||
$("#id_ipv4_address").prop("readOnly", false);
|
||||
$("#id_ipv4_address").prop("required", true);
|
||||
$("#id_ipv4_netmask").prop("readOnly", false);
|
||||
$("#id_ipv4_gateway").prop("readOnly", false);
|
||||
} else {
|
||||
$("#id_ipv4_address").val("");
|
||||
$("#id_ipv4_address").prop("readOnly", true);
|
||||
$("#id_ipv4_address").prop("required", false);
|
||||
$("#id_ipv4_netmask").val("");
|
||||
$("#id_ipv4_netmask").prop("readOnly", true);
|
||||
$("#id_ipv4_gateway").val("");
|
||||
$("#id_ipv4_gateway").prop("readOnly", true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -201,6 +201,27 @@ def get_first_ip_address_from_connection(connection):
|
||||
return output.strip().split(', ')[0].split('/')[0]
|
||||
|
||||
|
||||
def get_first_netmask_from_connection(connection):
|
||||
"""Return the first IP address of a connection setting.
|
||||
|
||||
XXX: Work around a bug in NetworkManager/Python GI. Remove after
|
||||
the bug if fixed.
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=756380.
|
||||
"""
|
||||
command = ['nmcli', '--terse', '--mode', 'tabular', '--fields',
|
||||
'ipv4.addresses', 'connection', 'show', connection.get_uuid()]
|
||||
|
||||
output = subprocess.check_output(command).decode()
|
||||
if '/' not in output:
|
||||
return None
|
||||
|
||||
CIDR = output.strip().split(', ')[0].split('/')[1]
|
||||
netmask = socket.inet_ntoa(struct.pack(">I", (0xffffffff <<
|
||||
(32 - int(CIDR))) &
|
||||
0xffffffff))
|
||||
return netmask
|
||||
|
||||
|
||||
def get_connection_list():
|
||||
"""Get a list of active and available connections."""
|
||||
active_uuids = []
|
||||
@ -291,7 +312,8 @@ def _update_common_settings(connection, connection_uuid, name, type_,
|
||||
return connection
|
||||
|
||||
|
||||
def _update_ipv4_settings(connection, ipv4_method, ipv4_address):
|
||||
def _update_ipv4_settings(connection, ipv4_method, ipv4_address, ipv4_netmask,
|
||||
ipv4_gateway, ipv4_dns, ipv4_second_dns):
|
||||
"""Edit IPv4 settings for network manager connections."""
|
||||
settings = nm.SettingIP4Config.new()
|
||||
connection.add_setting(settings)
|
||||
@ -299,22 +321,45 @@ def _update_ipv4_settings(connection, ipv4_method, ipv4_address):
|
||||
settings.set_property(nm.SETTING_IP_CONFIG_METHOD, ipv4_method)
|
||||
if ipv4_method == nm.SETTING_IP4_CONFIG_METHOD_MANUAL and ipv4_address:
|
||||
ipv4_address_int = ipv4_string_to_int(ipv4_address)
|
||||
ipv4_prefix = nm.utils_ip4_get_default_prefix(ipv4_address_int)
|
||||
if not ipv4_netmask:
|
||||
ipv4_netmask_int = nm.utils_ip4_get_default_prefix(
|
||||
ipv4_address_int)
|
||||
|
||||
address = nm.IPAddress.new(socket.AF_INET, ipv4_address, ipv4_prefix)
|
||||
ipv4_netmask_int = nm.utils_ip4_netmask_to_prefix(
|
||||
ipv4_string_to_int(ipv4_netmask))
|
||||
address = nm.IPAddress.new(socket.AF_INET, ipv4_address,
|
||||
ipv4_netmask_int)
|
||||
settings.add_address(address)
|
||||
|
||||
settings.set_property(nm.SETTING_IP_CONFIG_GATEWAY, '0.0.0.0')
|
||||
if ipv4_dns:
|
||||
settings.add_dns(ipv4_dns)
|
||||
if ipv4_second_dns:
|
||||
settings.add_dns(ipv4_second_dns)
|
||||
|
||||
if not ipv4_gateway:
|
||||
settings.set_property(nm.SETTING_IP_CONFIG_GATEWAY, '0.0.0.0')
|
||||
else:
|
||||
settings.set_property(nm.SETTING_IP_CONFIG_GATEWAY, ipv4_gateway)
|
||||
else:
|
||||
if ipv4_dns or ipv4_second_dns:
|
||||
settings.set_property(nm.SETTING_IP_CONFIG_IGNORE_AUTO_DNS, True)
|
||||
|
||||
if ipv4_dns:
|
||||
settings.add_dns(ipv4_dns)
|
||||
if ipv4_second_dns:
|
||||
settings.add_dns(ipv4_second_dns)
|
||||
|
||||
|
||||
def _update_ethernet_settings(connection, connection_uuid, name, interface,
|
||||
zone, ipv4_method, ipv4_address):
|
||||
zone, ipv4_method, ipv4_address, ipv4_netmask,
|
||||
ipv4_gateway, ipv4_dns, ipv4_second_dns):
|
||||
"""Create/edit ethernet settings for network manager connections."""
|
||||
type_ = '802-3-ethernet'
|
||||
|
||||
connection = _update_common_settings(connection, connection_uuid, name,
|
||||
type_, interface, zone)
|
||||
_update_ipv4_settings(connection, ipv4_method, ipv4_address)
|
||||
_update_ipv4_settings(connection, ipv4_method, ipv4_address, ipv4_netmask,
|
||||
ipv4_gateway, ipv4_dns, ipv4_second_dns)
|
||||
|
||||
# Ethernet
|
||||
settings = connection.get_setting_wired()
|
||||
@ -377,7 +422,9 @@ def edit_pppoe_connection(connection, name, interface, zone, username,
|
||||
connection.commit_changes(True)
|
||||
|
||||
|
||||
def add_ethernet_connection(name, interface, zone, ipv4_method, ipv4_address):
|
||||
def add_ethernet_connection(name, interface, zone, ipv4_method, ipv4_address,
|
||||
ipv4_netmask, ipv4_gateway, ipv4_dns,
|
||||
ipv4_second_dns):
|
||||
"""Add an automatic ethernet connection in network manager.
|
||||
|
||||
Return the UUID for the connection.
|
||||
@ -385,31 +432,34 @@ def add_ethernet_connection(name, interface, zone, ipv4_method, ipv4_address):
|
||||
connection_uuid = str(uuid.uuid4())
|
||||
connection = _update_ethernet_settings(
|
||||
None, connection_uuid, name, interface, zone, ipv4_method,
|
||||
ipv4_address)
|
||||
ipv4_address, ipv4_netmask, ipv4_gateway, ipv4_dns, ipv4_second_dns)
|
||||
client = nm.Client.new(None)
|
||||
client.add_connection_async(connection, True, None, _callback, None)
|
||||
return connection_uuid
|
||||
|
||||
|
||||
def edit_ethernet_connection(connection, name, interface, zone, ipv4_method,
|
||||
ipv4_address):
|
||||
ipv4_address, ipv4_netmask, ipv4_gateway,
|
||||
ipv4_dns, ipv4_second_dns):
|
||||
"""Edit an existing ethernet connection in network manager."""
|
||||
_update_ethernet_settings(
|
||||
connection, connection.get_uuid(), name, interface, zone, ipv4_method,
|
||||
ipv4_address)
|
||||
ipv4_address, ipv4_netmask, ipv4_gateway, ipv4_dns, ipv4_second_dns)
|
||||
connection.commit_changes(True)
|
||||
|
||||
|
||||
def _update_wifi_settings(connection, connection_uuid, name, interface, zone,
|
||||
ssid, mode, auth_mode, passphrase, ipv4_method,
|
||||
ipv4_address):
|
||||
ipv4_address, ipv4_netmask, ipv4_gateway, ipv4_dns,
|
||||
ipv4_second_dns):
|
||||
"""Create/edit wifi settings for network manager connections."""
|
||||
type_ = '802-11-wireless'
|
||||
key_mgmt = 'wpa-psk'
|
||||
|
||||
connection = _update_common_settings(connection, connection_uuid, name,
|
||||
type_, interface, zone)
|
||||
_update_ipv4_settings(connection, ipv4_method, ipv4_address)
|
||||
_update_ipv4_settings(connection, ipv4_method, ipv4_address, ipv4_netmask,
|
||||
ipv4_gateway, ipv4_dns, ipv4_second_dns)
|
||||
|
||||
# Wireless
|
||||
settings = connection.get_setting_wireless()
|
||||
@ -437,7 +487,8 @@ def _update_wifi_settings(connection, connection_uuid, name, interface, zone,
|
||||
|
||||
|
||||
def add_wifi_connection(name, interface, zone, ssid, mode, auth_mode,
|
||||
passphrase, ipv4_method, ipv4_address):
|
||||
passphrase, ipv4_method, ipv4_address, ipv4_netmask,
|
||||
ipv4_gateway, ipv4_dns, ipv4_second_dns):
|
||||
"""Add an automatic Wi-Fi connection in network manager.
|
||||
|
||||
Return the UUID for the connection.
|
||||
@ -445,18 +496,22 @@ def add_wifi_connection(name, interface, zone, ssid, mode, auth_mode,
|
||||
connection_uuid = str(uuid.uuid4())
|
||||
connection = _update_wifi_settings(
|
||||
None, connection_uuid, name, interface, zone, ssid, mode, auth_mode,
|
||||
passphrase, ipv4_method, ipv4_address)
|
||||
passphrase, ipv4_method, ipv4_address, ipv4_netmask,
|
||||
ipv4_gateway, ipv4_dns, ipv4_second_dns)
|
||||
client = nm.Client.new(None)
|
||||
client.add_connection_async(connection, True, None, _callback, None)
|
||||
return connection_uuid
|
||||
|
||||
|
||||
def edit_wifi_connection(connection, name, interface, zone, ssid, mode,
|
||||
auth_mode, passphrase, ipv4_method, ipv4_address):
|
||||
auth_mode, passphrase, ipv4_method, ipv4_address,
|
||||
ipv4_netmask, ipv4_gateway, ipv4_dns,
|
||||
ipv4_second_dns):
|
||||
"""Edit an existing wifi connection in network manager."""
|
||||
_update_wifi_settings(
|
||||
connection, connection.get_uuid(), name, interface, zone, ssid, mode,
|
||||
auth_mode, passphrase, ipv4_method, ipv4_address)
|
||||
auth_mode, passphrase, ipv4_method, ipv4_address, ipv4_netmask,
|
||||
ipv4_gateway, ipv4_dns, ipv4_second_dns)
|
||||
connection.commit_changes(True)
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user