From bf015614b6de55455409a0be689b60577d13d1bd Mon Sep 17 00:00:00 2001 From: Fabian Hauser Date: Mon, 23 Dec 2019 21:29:42 +0000 Subject: [PATCH] Add wwan networking --- host/achiles.nix | 6 +- role/networking/wwan.nix | 143 ++++++++++++------------------ role/networking/wwan/mbim-ip.bash | 40 +++++---- role/router.nix | 10 +-- 4 files changed, 88 insertions(+), 111 deletions(-) diff --git a/host/achiles.nix b/host/achiles.nix index 3946814..6fa34fa 100644 --- a/host/achiles.nix +++ b/host/achiles.nix @@ -5,7 +5,7 @@ { config, pkgs, ... }: let routerConfig = { - wanCardAddress = "00:0d:b9:51:a2:74"; + wanInterface = "wwp0s19u1u3i12"; wireless = { wleInterface = "wlp5s0"; wleSSID = "hauser"; @@ -25,12 +25,13 @@ let routerConfig = { in { + imports = [ ../hardware/apu.nix ../hardware/wle900vx.nix ../role/base.nix - ../role/wwan.nix + ../role/networking/wwan.nix (import ../role/router.nix routerConfig) ]; @@ -45,6 +46,7 @@ in ]; services.wwan = { + enable = true; apn = "gprs.swisscom.ch"; networkInterface = "wwp0s19u1u3i12"; }; diff --git a/role/networking/wwan.nix b/role/networking/wwan.nix index 121dcb3..e015053 100644 --- a/role/networking/wwan.nix +++ b/role/networking/wwan.nix @@ -7,92 +7,65 @@ with lib; let cfg = config.services.wwan; - mbim-ip = pkgs.writeScriptBin "mbim-ip" readFile ./wwan/mbim-ip.bash; - mbim-ip-configured = pkgs.writeScriptBin "mbim-ip-configured" '' + mbim-ip-configured = pkgs.writeScriptBin "mbim-ip-configured" ('' #!${pkgs.stdenv.shell} - MBIM_BINARY=${pkgs.libmbim}/bin/mbimcli MBIM_INTERFACE=${cfg.mbimInterface} - exec ${mbim-ip} $@ - ''; + '' + (readFile ./wwan/mbim-ip.bash)); in { - options = { - services.wwan = { - enable = mkEnableOption "wwan client service"; + options.services.wwan = { + enable = mkEnableOption "wwan client service"; - config = mkOption { - type = types.attrsOf (types.submodule ( - { - options = { - apn = mkOption { - type = types.str; - description = '' - APN domain of provider. - ''; - }; + apn = mkOption { + type = types.str; + description = '' + APN domain of provider. + ''; + }; - apnUser = mkOption { - type = types.str; - default = ""; - description = '' - APN username (optional). - ''; - }; + apnUser = mkOption { + type = types.str; + default = ""; + description = '' + APN username (optional). + ''; + }; - apnPass = mkOption { - type = types.str; - default = ""; - description = '' - APN password (optional). - ''; - }; + apnPass = mkOption { + type = types.str; + default = ""; + description = '' + APN password (optional). + ''; + }; - apnAuth = mkOption { - type = types.enum; - values = [ "PAP" "CHAP" "MSCHAPV2" "" ]; - default = ""; - description = '' - APN authentication type, one of ${concatMapStringsSep ", " show values} (optional). - ''; - }; + apnAuth = mkOption { + type = types.enum [ "PAP" "CHAP" "MSCHAPV2" "" ]; + default = ""; + description = '' + APN authentication type, one of ${concatMapStringsSep ", " show values} (optional). + ''; + }; - mbimProxy = mkOption { - type = types.bool; - default = true; - description = '' - Whether to use the mbim proxy or not. - ''; - }; + mbimProxy = mkOption { + type = types.bool; + default = true; + description = '' + Whether to use the mbim proxy or not. + ''; + }; - mbimInterface = mkOption { - type = types.path; - default = /dev/cdc-wdm0 - description = "MBIM Interface which the connection will use."; - }; + mbimInterface = mkOption { + type = types.str; + default = "/dev/cdc-wdm0"; + description = '' + MBIM Interface which the connection will use. + ''; + }; - networkInterface = mkOption { - type = types.str; - description = "Name of the WWAN network interface"; - }; - }; - } - )); - - default = {}; - - example = literalExample '' - { - wwan = { - apn = "gprs.swisscom.ch"; - networkInterface = "wwp0s19u1u3i12"; - }; - } - ''; - - description = '' - Configuration for WWAN connectivity using a MBIM capable card. - ''; - }; + networkInterface = mkOption { + type = types.str; + description = "Name of the WWAN network interface"; }; }; @@ -100,27 +73,25 @@ in systemd.services."wwan" = { description = "WWAN connectivity"; wantedBy = [ "network.target" ]; - wants = [ "sys-subsystem-net-devices-${cfg.networkInterface}.device"]; + bindsTo = [ "network-addresses-${cfg.networkInterface}.service" ]; + path = [ pkgs.libmbim pkgs.iproute ]; serviceConfig = { - ExecStart = "@${pkgs.libmbim}/bin/mbim-network ${toString cfg.mbimInterface} start"; - ExecStop = "@${pkgs.libmbim}/bin/mbim-network ${toString cfg.mbimInterface} stop"; - - # MBIM networking is a special fellow - it gets the IP address for us, - # but we need to manually set it to the interface - ExecStartPost = "@${mbim-ip-configured} start ${cfg.networkInterface}"; - ExecStopPre = "@${mbim-ip-configured} stop ${cfg.networkInterface}"; + ExecStart = "${mbim-ip-configured}/bin/mbim-ip-configured start ${cfg.networkInterface}"; + ExecStop = "${mbim-ip-configured}/bin/mbim-ip-configured stop ${cfg.networkInterface}"; RemainAfterExit = true; }; }; - environment.etc."/etc/mbim-network.conf".text = '' - APN=${cfg.apnUser} + environment.etc."mbim-network.conf".text = '' + APN=${cfg.apn} APN_USER=${cfg.apnUser} APN_PASS=${cfg.apnPass} APN_AUTH=${cfg.apnAuth} - PROXY=${optionalString cfg.proxy "yes"} + PROXY=${optionalString cfg.mbimProxy "yes"} ''; + + networking.interfaces.${cfg.networkInterface}.useDHCP = false; }; } diff --git a/role/networking/wwan/mbim-ip.bash b/role/networking/wwan/mbim-ip.bash index 6413b37..fafc841 100644 --- a/role/networking/wwan/mbim-ip.bash +++ b/role/networking/wwan/mbim-ip.bash @@ -13,10 +13,6 @@ if [ "$MBIM_INTERFACE" == "" ]; then MBIM_INTERFACE="/dev/cdc-wdm0" fi -if [ "$MBIM_BINARY" == "" ]; then - MBIM_BINARY=mbimcli -fi - ############################################################################### # Global Variables ############################################################################### @@ -32,6 +28,10 @@ ipv6_gateway="" ipv6_dns=() ipv6_mtu="" +export previous_state state skip_line \ + ipv4_addresses ipv4_gateway ipv4_dns ipv4_mtu \ + ipv6_addresses ipv6_gateway ipv6_dns ipv6_mtu + ############################################################################### # Function ############################################################################### @@ -124,13 +124,13 @@ function parse_input_state_machine { state="start" while true; do if [[ "$skip_line" == 0 ]]; then - read line + read line || break # TODO: Clean up else skip_line=0 fi case "$state" in "start") - read line # first line is empty, read a new one #TODO: This is not very clean... + read line || break # first line is empty, read a new one #TODO: This is not very clean... case "$line" in *"configuration available: 'none'"*) # Skip none state @@ -267,17 +267,17 @@ function parse_input_state_machine { } -interface_start(){ +interface_stop(){ ip addr flush dev $DEV ip route flush dev $DEV ip -6 addr flush dev $DEV - ip -6 p route flush dev $DEV + ip -6 route flush dev $DEV #TODO: Nameserver? } -interface_stop() { +interface_start() { ip link set $DEV up if [[ "${#ipv4_addresses[@]}" > 0 ]]; then @@ -285,6 +285,8 @@ interface_stop() { ip link set $DEV mtu $ipv4_mtu ip route add default via $ipv4_gateway dev $DEV #TODO: nameserver ${ipv4_dns[@]} + else + echo "No IPv4 address, skipping v4 configuration..." fi if [[ "${#ipv6_addresses[@]}" > 0 ]]; then @@ -292,6 +294,8 @@ interface_stop() { ip -6 route add default via $ipv6_gateway dev $DEV ip -6 link set $DEV mtu $ipv6_mtu #TODO: nameserver ${ipv6_dns[@]}" + else + echo "No IPv6 address, skipping v6 configuration..." fi } @@ -299,21 +303,27 @@ interface_stop() { # Execution ############################################################################### set -x +set -e echo "NOTE: This script does not yet support nameserver configuration." -parse_input_state_machine <(${MBIM_BINARY} -d ${MBIM_INTERFACE} -p --query-ip-configuration=0) -print_full_configuration - case "$MODE" in "start") - interface_stop + mbim-network $MBIM_INTERFACE start + sleep 1 + mbimcli -d $MBIM_INTERFACE -p --query-ip-configuration=0 | { + parse_input_state_machine + print_full_configuration + interface_stop + interface_start + } ;; "stop") - interface_start + mbim-network $MBIM_INTERFACE stop + interface_stop ;; *) echo "USAGE: $0 start|stop INTERFACE" >&2 echo "You can set an env variable DEBUG to gather debugging output." >&2 exit 1 ;; -esac \ No newline at end of file +esac diff --git a/role/router.nix b/role/router.nix index 5b2dab5..5ce83f9 100644 --- a/role/router.nix +++ b/role/router.nix @@ -1,7 +1,7 @@ { # To get the MAC address of each card, use this command: cat /sys/class/net/*device_name*/address # Make sure to use the lower-case hex values in your udev rules. It does not like upper-case. - wanCardAddress ? "00:0d:b9:48:55:be", + wanInterface, wireless ? { wleInterface = "wlp5s0"; wleSSID = "hauser"; @@ -26,17 +26,11 @@ in (import ./networking/wireless-access-point.nix wireless) (import ./networking/dns-recursive.nix lanNetwork) ]; - - # To get the MAC address of each card, use this command: cat /sys/class/net/*device_name*/address - # Make sure to use the lower-case hex values in your udev rules. It does not like upper-case. - services.udev.extraRules = '' - SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="${wanCardAddress}", NAME="wan" - ''; networking = { nat = { enable = true; - externalInterface = "wan"; + externalInterface = wanInterface; internalInterfaces = [ "lan" ]; };