diff --git a/.gitlab/tests/cram/generic/acceleration-plan-components/132-tr181-wireguard.t b/.gitlab/tests/cram/generic/acceleration-plan-components/132-tr181-wireguard.t new file mode 100644 index 0000000000..daa3802f4b --- /dev/null +++ b/.gitlab/tests/cram/generic/acceleration-plan-components/132-tr181-wireguard.t @@ -0,0 +1,39 @@ +Create R alias: + + $ alias R="${CRAM_REMOTE_COMMAND:-}" + +Check the WireGuard datamodel starts empty: + + $ R "ba-cli 'WireGuard.PeerNumberOfEntries?'" | grep -v '>' | grep -F 'NumberOfEntries=' + WireGuard.PeerNumberOfEntries=0 + $ R "ba-cli 'WireGuard.TunnelNumberOfEntries?'" | grep -v '>' | grep -F 'NumberOfEntries=' + WireGuard.TunnelNumberOfEntries=0 + +Create a Wireguard tunnel interface: + + $ R "ba-cli 'WireGuard.Tunnel.+{Alias=\"t1\"}'" > /dev/null 2>&1 + $ R "ba-cli 'WireGuard.Tunnel.t1.Interface.+{Alias=\"i1\"}'" > /dev/null 2>&1 + $ WGIFACE=`R "ba-cli 'WireGuard.Tunnel.t1.Interface.i1.Name?'" | sed -ne 2p | awk -F= '{print $2}' | sed -e s/'\"'//g` + $ R "ba-cli 'WireGuard.Tunnel.t1.Interface.i1.Status?'" | sed -ne 2p + WireGuard.Tunnel.*.Interface.1.Status="Down" (glob) + +Verify status in NetModel: + + $ R "ba-cli 'NetModel.Intf.[Name ~= \""$WGIFACE"\"].Status_ext?'" | grep -v '>' | grep -F 'Status_ext=' + NetModel.Intf.*.Status_ext="Down" (glob) + +Now enable the interface + + $ R "ba-cli 'WireGuard.Tunnel.t1.Interface.i1.Enable=1'" > /dev/null 2>&1 + $ R "ba-cli 'WireGuard.Tunnel.t1.Enable=1'" > /dev/null 2>&1 + $ R "ba-cli 'WireGuard.Tunnel.t1.Interface.i1.Status?'" | sed -ne 2p + WireGuard.Tunnel.*.Interface.1.Status="Unknown" (glob) + +Verify status in NetModel: + + $ R "ba-cli 'NetModel.Intf.[Name ~= \""$WGIFACE"\"].Status_ext?'" | grep -v '>' | grep -F 'Status_ext=' + NetModel.Intf.*.Status_ext="Unknown" (glob) + +Cleanup: + + $ R "ba-cli 'WireGuard.Tunnel.t1-'" >/dev/null 2>&1 diff --git a/.gitlab/tests/cram/generic/acceleration-plan-components/132-wireguard-e2e.t b/.gitlab/tests/cram/generic/acceleration-plan-components/132-wireguard-e2e.t new file mode 100644 index 0000000000..6eb0e46086 --- /dev/null +++ b/.gitlab/tests/cram/generic/acceleration-plan-components/132-wireguard-e2e.t @@ -0,0 +1,91 @@ +End-to-end WireGuard tunnel test. The remote peer runs in a network +namespace on the DUT, connected through a veth pair that emulates the +WAN link, so the test is self-contained. + +Create R alias: + + $ alias R="${CRAM_REMOTE_COMMAND:-}" + + $ R logger -t cram "Starting WireGuard E2E test" + +Create the peer network namespace with a veth link emulating the WAN: + + $ R "(ip netns add wgpeer; \ + > ip link add veth-wg type veth peer name veth-wgp; \ + > ip link set veth-wgp netns wgpeer; \ + > ip addr add 192.168.77.1/24 dev veth-wg; \ + > ip link set veth-wg up; \ + > ip netns exec wgpeer ip addr add 192.168.77.2/24 dev veth-wgp; \ + > ip netns exec wgpeer ip link set veth-wgp up; \ + > ip netns exec wgpeer ip link set lo up) > /dev/null 2>&1" + +Configure the WireGuard peer endpoint inside the namespace: + + $ R "(umask 077; wg genkey > /tmp/wgpeer.key && wg pubkey < /tmp/wgpeer.key > /tmp/wgpeer.pub) 2>&1" + $ R "(ip netns exec wgpeer ip link add wg-peer type wireguard; \ + > ip netns exec wgpeer wg set wg-peer private-key /tmp/wgpeer.key listen-port 51820; \ + > ip netns exec wgpeer ip addr add 10.0.10.5/24 dev wg-peer; \ + > ip netns exec wgpeer ip link set wg-peer up) > /dev/null 2>&1" + $ WGPEERPUB=$(R "cat /tmp/wgpeer.pub") + +Configure the CPE tunnel through the data model: + + $ WGTIDX=$(R "ba-cli 'WireGuard.Tunnel.+{Alias=\"e2e\"}'" 2>/dev/null | sed -ne 's/^WireGuard.Tunnel.\([0-9]\+\).$/\1/p') + $ R "ba-cli 'WireGuard.Tunnel.e2e.Interface.+{Alias=\"i1\",Enable=1}'" > /dev/null 2>&1 + $ WGPIDX=$(R "ba-cli 'WireGuard.Peer.+{Alias=\"peer1\",AllowedIPs=\"10.0.10.5/32\",PublicKey=\"$WGPEERPUB\",EndpointAddress=\"192.168.77.2\",EndpointPort=51820,Enable=1}'" 2>/dev/null | sed -ne 's/^WireGuard.Peer.\([0-9]\+\).$/\1/p') + $ R "ba-cli 'WireGuard.Tunnel.e2e.PeerReferences=\"Device.WireGuard.Peer.$WGPIDX\"'" > /dev/null 2>&1 + $ R "ba-cli 'WireGuard.Tunnel.e2e.Enable=1'" > /dev/null 2>&1 + $ sleep 3 + +Point the namespace peer at the CPE endpoint: + + $ CPEPUB=$(R "ba-cli 'WireGuard.Tunnel.e2e.PublicKey?'" | sed -ne 's/.*PublicKey="\(.*\)"$/\1/p') + $ CPEPORT=$(R "ba-cli 'WireGuard.Tunnel.e2e.ListenPort?'" | sed -ne 's/.*ListenPort=\([0-9]\+\).*/\1/p') + $ R "ip netns exec wgpeer wg set wg-peer peer \"$CPEPUB\" allowed-ips 10.0.10.1/32 endpoint 192.168.77.1:$CPEPORT persistent-keepalive 5" + +Assign an IPv4 address to the CPE tunnel interface through the data model: + + $ IPIDX=$(R "ba-cli 'IP.Interface.+{Alias=\"wg-e2e\",Enable=1,IPv4Enable=1,LowerLayers=\"Device.WireGuard.Tunnel.$WGTIDX.Interface.1.\",Router=\"Device.Routing.Router.1.\"}'" 2>/dev/null | sed -ne 's/^IP.Interface.\([0-9]\+\).$/\1/p') + $ R "ba-cli 'IP.Interface.$IPIDX.IPv4Address.+{Alias=\"wg-e2e\",AddressingType=\"Static\",IPAddress=\"10.0.10.1\",SubnetMask=\"255.255.255.0\",Enable=1}'" > /dev/null 2>&1 + $ sleep 3 + +Send traffic through the tunnel (CPE to peer): + + $ R "ping -c 3 -W 10 10.0.10.5 > /dev/null 2>&1; echo \$?" + 0 + +Verify the handshake completed on the peer side: + + $ R "ip netns exec wgpeer wg show wg-peer latest-handshakes | awk '{print ((\$2 > 0) ? \"handshake-ok\" : \"no-handshake\")}'" + handshake-ok + +Accept tunnel traffic towards the CPE and ping from the peer (WAN to LAN direction): + + $ R "ba-cli 'Firewall.Service.+{Alias=\"wge2e\",SourcePrefixes=\"10.0.10.0/24\",Protocol=1,Interface=\"Device.WireGuard.Tunnel.$WGTIDX.Interface.1\",IPVersion=4,Enable=1}'" > /dev/null 2>&1 + $ sleep 2 + $ R "ip netns exec wgpeer ping -c 3 -W 10 10.0.10.1 > /dev/null 2>&1; echo \$?" + 0 + +Run a short throughput test through the tunnel: + + $ R "ip netns exec wgpeer iperf3 -s -D > /dev/null 2>&1" + $ sleep 1 + $ R "iperf3 -c 10.0.10.5 -t 2 > /dev/null 2>&1; echo \$?" + 0 + $ R "killall iperf3 > /dev/null 2>&1; true" + +The WireGuard interface is present in NetModel: + + $ WGIFACE=$(R "ba-cli 'WireGuard.Tunnel.e2e.Interface.1.Name?'" | sed -ne 's/.*Name="\(.*\)"$/\1/p') + $ R "ba-cli 'NetModel.Intf.[Name ~= \""$WGIFACE"\"].Flags?'" | grep -v '>' | grep -F 'Flags=' | grep -c 'wireguard' + 1 + +Cleanup: + + $ R "ba-cli 'Firewall.Service.wge2e-'" > /dev/null 2>&1 + $ R "ba-cli 'IP.Interface.$IPIDX.-'" > /dev/null 2>&1 + $ R "ba-cli 'WireGuard.Tunnel.e2e-'" > /dev/null 2>&1 + $ R "ba-cli 'WireGuard.Peer.peer1-'" > /dev/null 2>&1 + $ R "(ip netns del wgpeer; rm -f /tmp/wgpeer.key /tmp/wgpeer.pub) > /dev/null 2>&1; true" + + $ R logger -t cram "WireGuard E2E test finished" diff --git a/.gitlab/tests/cram/generic/fixtures/obuspa.expected b/.gitlab/tests/cram/generic/fixtures/obuspa.expected index 88b7bf5d5a..73324dfc74 100644 --- a/.gitlab/tests/cram/generic/fixtures/obuspa.expected +++ b/.gitlab/tests/cram/generic/fixtures/obuspa.expected @@ -5344,6 +5344,58 @@ Device.WiFi.bSTAMLD.{i}.bSTAMLDConfig.STREnabled Device.WiFi.bSTAMLDMaxLinks proto::prplmesh-dm-mapper Device.WiFi.bSTAMLDNumberOfEntries proto::prplmesh-dm-mapper Device.WiFi.wps_DefParam. proto::prplmesh-dm-mapper +Device.WireGuard. proto::tr181-wireguard +Device.WireGuard.Peer.{i}. proto::tr181-wireguard +Device.WireGuard.Peer.{i}.Alias proto::tr181-wireguard +Device.WireGuard.Peer.{i}.AllowedIPs proto::tr181-wireguard +Device.WireGuard.Peer.{i}.Enable proto::tr181-wireguard +Device.WireGuard.Peer.{i}.EndpointAddress proto::tr181-wireguard +Device.WireGuard.Peer.{i}.EndpointPort proto::tr181-wireguard +Device.WireGuard.Peer.{i}.LastHandshakeTime proto::tr181-wireguard +Device.WireGuard.Peer.{i}.PersistentKeepalive proto::tr181-wireguard +Device.WireGuard.Peer.{i}.PresharedKey proto::tr181-wireguard +Device.WireGuard.Peer.{i}.PublicKey proto::tr181-wireguard +Device.WireGuard.PeerNumberOfEntries proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}. proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Alias proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Enable proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}. proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Alias proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Enable proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.LastChange proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.LowerLayers proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Name proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats. proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.BroadcastPacketsReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.BroadcastPacketsSent proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.BytesReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.BytesSent proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.DiscardPacketsReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.DiscardPacketsSent proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.ErrorsReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.ErrorsSent proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.MulticastPacketsReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.MulticastPacketsSent proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.PacketsReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.PacketsSent proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.UnicastPacketsReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.UnicastPacketsSent proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Stats.UnknownProtoPacketsReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Interface.{i}.Status proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.InterfaceNumberOfEntries proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.ListenPort proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.PeerReferences proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.PrivateKey proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.PublicKey proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Stats. proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Stats.BytesReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Stats.BytesSent proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Stats.ErrorsReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Stats.ErrorsSent proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Stats.PacketsReceived proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Stats.PacketsSent proto::tr181-wireguard +Device.WireGuard.Tunnel.{i}.Status proto::tr181-wireguard +Device.WireGuard.TunnelNumberOfEntries proto::tr181-wireguard Device.XPON. proto::tr181-xpon Device.XPON.ONU.{i}. proto::tr181-xpon Device.XPON.ONU.{i}.ANI.{i}. proto::tr181-xpon diff --git a/.gitlab/tests/cram/generic/ubus-datamodel-list.t b/.gitlab/tests/cram/generic/ubus-datamodel-list.t index 8156e2c970..df998890ab 100644 --- a/.gitlab/tests/cram/generic/ubus-datamodel-list.t +++ b/.gitlab/tests/cram/generic/ubus-datamodel-list.t @@ -132,6 +132,7 @@ Check that ubus has expected datamodels available: Device.UserInterface Device.Users Device.WiFi + Device.WireGuard Device.XPON Device.X_PRPLWARE-COM_Buttons Device.X_PRPLWARE-COM_ConMon @@ -439,6 +440,9 @@ Check that ubus has expected datamodels available: WiFiScheduler.Group.Schedule WiFiScheduler.Network WiFiScheduler.Network.Schedule + WireGuard + WireGuard.Peer + WireGuard.Tunnel XPON XPON.ONU X_PRPLWARE-COM_Agent diff --git a/.gitlab/tests/cram/generic/verify-config-restore/020-verify-backup-restore-flags.t b/.gitlab/tests/cram/generic/verify-config-restore/020-verify-backup-restore-flags.t index 3d3f11b567..c2c97ba0a2 100644 --- a/.gitlab/tests/cram/generic/verify-config-restore/020-verify-backup-restore-flags.t +++ b/.gitlab/tests/cram/generic/verify-config-restore/020-verify-backup-restore-flags.t @@ -25,6 +25,7 @@ PPW-1729, PPW-1731 and PPW-1786: /etc/amx/tr181-cpu/tr181-cpu_definition.odl /etc/amx/tr181-gre/tr181-gre_definition.odl /etc/amx/tr181-usb/tr181-usb_port.odl + /etc/amx/tr181-wireguard/tr181-wireguard_definition.odl $ R "grep -r %usersetting /etc/amx | grep -vE '(upc.odl|.*default.*)' "\ > " | sed -E 's#:.*##' | sort | uniq"