mirror of
https://github.com/qdm12/gluetun.git
synced 2025-12-11 13:56:50 -06:00
chore(all): use netip.Prefix for ip networks
- remove usage of `net.IPNet` - remove usage of `netaddr.IPPrefix`
This commit is contained in:
parent
801a7fd6fe
commit
d21a943779
@ -2,7 +2,7 @@ package settings
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net/netip"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings/helpers"
|
"github.com/qdm12/gluetun/internal/configuration/settings/helpers"
|
||||||
"github.com/qdm12/gotree"
|
"github.com/qdm12/gotree"
|
||||||
@ -12,7 +12,7 @@ import (
|
|||||||
type Firewall struct {
|
type Firewall struct {
|
||||||
VPNInputPorts []uint16
|
VPNInputPorts []uint16
|
||||||
InputPorts []uint16
|
InputPorts []uint16
|
||||||
OutboundSubnets []net.IPNet
|
OutboundSubnets []netip.Prefix
|
||||||
Enabled *bool
|
Enabled *bool
|
||||||
Debug *bool
|
Debug *bool
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ func (f *Firewall) copy() (copied Firewall) {
|
|||||||
return Firewall{
|
return Firewall{
|
||||||
VPNInputPorts: helpers.CopyUint16Slice(f.VPNInputPorts),
|
VPNInputPorts: helpers.CopyUint16Slice(f.VPNInputPorts),
|
||||||
InputPorts: helpers.CopyUint16Slice(f.InputPorts),
|
InputPorts: helpers.CopyUint16Slice(f.InputPorts),
|
||||||
OutboundSubnets: helpers.CopyIPNetSlice(f.OutboundSubnets),
|
OutboundSubnets: helpers.CopyNetipPrefixesSlice(f.OutboundSubnets),
|
||||||
Enabled: helpers.CopyBoolPtr(f.Enabled),
|
Enabled: helpers.CopyBoolPtr(f.Enabled),
|
||||||
Debug: helpers.CopyBoolPtr(f.Debug),
|
Debug: helpers.CopyBoolPtr(f.Debug),
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ func (f *Firewall) copy() (copied Firewall) {
|
|||||||
func (f *Firewall) mergeWith(other Firewall) {
|
func (f *Firewall) mergeWith(other Firewall) {
|
||||||
f.VPNInputPorts = helpers.MergeUint16Slices(f.VPNInputPorts, other.VPNInputPorts)
|
f.VPNInputPorts = helpers.MergeUint16Slices(f.VPNInputPorts, other.VPNInputPorts)
|
||||||
f.InputPorts = helpers.MergeUint16Slices(f.InputPorts, other.InputPorts)
|
f.InputPorts = helpers.MergeUint16Slices(f.InputPorts, other.InputPorts)
|
||||||
f.OutboundSubnets = helpers.MergeIPNetsSlices(f.OutboundSubnets, other.OutboundSubnets)
|
f.OutboundSubnets = helpers.MergeNetipPrefixesSlices(f.OutboundSubnets, other.OutboundSubnets)
|
||||||
f.Enabled = helpers.MergeWithBool(f.Enabled, other.Enabled)
|
f.Enabled = helpers.MergeWithBool(f.Enabled, other.Enabled)
|
||||||
f.Debug = helpers.MergeWithBool(f.Debug, other.Debug)
|
f.Debug = helpers.MergeWithBool(f.Debug, other.Debug)
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ func (f *Firewall) mergeWith(other Firewall) {
|
|||||||
func (f *Firewall) overrideWith(other Firewall) {
|
func (f *Firewall) overrideWith(other Firewall) {
|
||||||
f.VPNInputPorts = helpers.OverrideWithUint16Slice(f.VPNInputPorts, other.VPNInputPorts)
|
f.VPNInputPorts = helpers.OverrideWithUint16Slice(f.VPNInputPorts, other.VPNInputPorts)
|
||||||
f.InputPorts = helpers.OverrideWithUint16Slice(f.InputPorts, other.InputPorts)
|
f.InputPorts = helpers.OverrideWithUint16Slice(f.InputPorts, other.InputPorts)
|
||||||
f.OutboundSubnets = helpers.OverrideWithIPNetsSlice(f.OutboundSubnets, other.OutboundSubnets)
|
f.OutboundSubnets = helpers.OverrideWithNetipPrefixesSlice(f.OutboundSubnets, other.OutboundSubnets)
|
||||||
f.Enabled = helpers.OverrideWithBool(f.Enabled, other.Enabled)
|
f.Enabled = helpers.OverrideWithBool(f.Enabled, other.Enabled)
|
||||||
f.Debug = helpers.OverrideWithBool(f.Debug, other.Debug)
|
f.Debug = helpers.OverrideWithBool(f.Debug, other.Debug)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,30 +90,6 @@ func CopyIP(original net.IP) (copied net.IP) {
|
|||||||
return copied
|
return copied
|
||||||
}
|
}
|
||||||
|
|
||||||
func CopyIPNet(original net.IPNet) (copied net.IPNet) {
|
|
||||||
if original.IP != nil {
|
|
||||||
copied.IP = make(net.IP, len(original.IP))
|
|
||||||
copy(copied.IP, original.IP)
|
|
||||||
}
|
|
||||||
|
|
||||||
if original.Mask != nil {
|
|
||||||
copied.Mask = make(net.IPMask, len(original.Mask))
|
|
||||||
copy(copied.Mask, original.Mask)
|
|
||||||
}
|
|
||||||
|
|
||||||
return copied
|
|
||||||
}
|
|
||||||
|
|
||||||
func CopyIPNetPtr(original *net.IPNet) (copied *net.IPNet) {
|
|
||||||
if original == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
copied = new(net.IPNet)
|
|
||||||
*copied = CopyIPNet(*original)
|
|
||||||
return copied
|
|
||||||
}
|
|
||||||
|
|
||||||
func CopyNetipAddress(original netip.Addr) (copied netip.Addr) {
|
func CopyNetipAddress(original netip.Addr) (copied netip.Addr) {
|
||||||
// AsSlice creates a new byte slice so no need to copy the bytes.
|
// AsSlice creates a new byte slice so no need to copy the bytes.
|
||||||
bytes := original.AsSlice()
|
bytes := original.AsSlice()
|
||||||
@ -158,18 +134,6 @@ func CopyUint16Slice(original []uint16) (copied []uint16) {
|
|||||||
return copied
|
return copied
|
||||||
}
|
}
|
||||||
|
|
||||||
func CopyIPNetSlice(original []net.IPNet) (copied []net.IPNet) {
|
|
||||||
if original == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
copied = make([]net.IPNet, len(original))
|
|
||||||
for i := range original {
|
|
||||||
copied[i] = CopyIPNet(original[i])
|
|
||||||
}
|
|
||||||
return copied
|
|
||||||
}
|
|
||||||
|
|
||||||
func CopyNetipPrefixesSlice(original []netip.Prefix) (copied []netip.Prefix) {
|
func CopyNetipPrefixesSlice(original []netip.Prefix) (copied []netip.Prefix) {
|
||||||
if original == nil {
|
if original == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -187,32 +187,6 @@ func MergeUint16Slices(a, b []uint16) (result []uint16) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func MergeIPNetsSlices(a, b []net.IPNet) (result []net.IPNet) {
|
|
||||||
if a == nil && b == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
seen := make(map[string]struct{}, len(a)+len(b))
|
|
||||||
result = make([]net.IPNet, 0, len(a)+len(b))
|
|
||||||
for _, ipNet := range a {
|
|
||||||
key := ipNet.String()
|
|
||||||
if _, ok := seen[key]; ok {
|
|
||||||
continue // duplicate
|
|
||||||
}
|
|
||||||
result = append(result, ipNet)
|
|
||||||
seen[key] = struct{}{}
|
|
||||||
}
|
|
||||||
for _, ipNet := range b {
|
|
||||||
key := ipNet.String()
|
|
||||||
if _, ok := seen[key]; ok {
|
|
||||||
continue // duplicate
|
|
||||||
}
|
|
||||||
result = append(result, ipNet)
|
|
||||||
seen[key] = struct{}{}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func MergeNetipAddressesSlices(a, b []netip.Addr) (result []netip.Addr) {
|
func MergeNetipAddressesSlices(a, b []netip.Addr) (result []netip.Addr) {
|
||||||
if a == nil && b == nil {
|
if a == nil && b == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -145,15 +145,6 @@ func OverrideWithUint16Slice(existing, other []uint16) (result []uint16) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func OverrideWithIPNetsSlice(existing, other []net.IPNet) (result []net.IPNet) {
|
|
||||||
if other == nil {
|
|
||||||
return existing
|
|
||||||
}
|
|
||||||
result = make([]net.IPNet, len(other))
|
|
||||||
copy(result, other)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func OverrideWithNetipAddressesSlice(existing, other []netip.Addr) (result []netip.Addr) {
|
func OverrideWithNetipAddressesSlice(existing, other []netip.Addr) (result []netip.Addr) {
|
||||||
if other == nil {
|
if other == nil {
|
||||||
return existing
|
return existing
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package settings
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net/netip"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings/helpers"
|
"github.com/qdm12/gluetun/internal/configuration/settings/helpers"
|
||||||
@ -22,7 +22,7 @@ type Wireguard struct {
|
|||||||
// It cannot be nil in the internal state.
|
// It cannot be nil in the internal state.
|
||||||
PreSharedKey *string
|
PreSharedKey *string
|
||||||
// Addresses are the Wireguard interface addresses.
|
// Addresses are the Wireguard interface addresses.
|
||||||
Addresses []net.IPNet
|
Addresses []netip.Prefix
|
||||||
// Interface is the name of the Wireguard interface
|
// Interface is the name of the Wireguard interface
|
||||||
// to create. It cannot be the empty string in the
|
// to create. It cannot be the empty string in the
|
||||||
// internal state.
|
// internal state.
|
||||||
@ -78,13 +78,12 @@ func (w Wireguard) validate(vpnProvider string, ipv6Supported bool) (err error)
|
|||||||
return fmt.Errorf("%w", ErrWireguardInterfaceAddressNotSet)
|
return fmt.Errorf("%w", ErrWireguardInterfaceAddressNotSet)
|
||||||
}
|
}
|
||||||
for i, ipNet := range w.Addresses {
|
for i, ipNet := range w.Addresses {
|
||||||
if ipNet.IP == nil || ipNet.Mask == nil {
|
if !ipNet.IsValid() {
|
||||||
return fmt.Errorf("%w: for address at index %d: %s",
|
return fmt.Errorf("%w: for address at index %d: %s",
|
||||||
ErrWireguardInterfaceAddressNotSet, i, ipNet.String())
|
ErrWireguardInterfaceAddressNotSet, i, ipNet.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
ipv6Net := ipNet.IP.To4() == nil
|
if !ipv6Supported && ipNet.Addr().Is6() {
|
||||||
if ipv6Net && !ipv6Supported {
|
|
||||||
return fmt.Errorf("%w: address %s",
|
return fmt.Errorf("%w: address %s",
|
||||||
ErrWireguardInterfaceAddressIPv6, ipNet)
|
ErrWireguardInterfaceAddressIPv6, ipNet)
|
||||||
}
|
}
|
||||||
@ -109,7 +108,7 @@ func (w *Wireguard) copy() (copied Wireguard) {
|
|||||||
return Wireguard{
|
return Wireguard{
|
||||||
PrivateKey: helpers.CopyStringPtr(w.PrivateKey),
|
PrivateKey: helpers.CopyStringPtr(w.PrivateKey),
|
||||||
PreSharedKey: helpers.CopyStringPtr(w.PreSharedKey),
|
PreSharedKey: helpers.CopyStringPtr(w.PreSharedKey),
|
||||||
Addresses: helpers.CopyIPNetSlice(w.Addresses),
|
Addresses: helpers.CopyNetipPrefixesSlice(w.Addresses),
|
||||||
Interface: w.Interface,
|
Interface: w.Interface,
|
||||||
Implementation: w.Implementation,
|
Implementation: w.Implementation,
|
||||||
}
|
}
|
||||||
@ -118,7 +117,7 @@ func (w *Wireguard) copy() (copied Wireguard) {
|
|||||||
func (w *Wireguard) mergeWith(other Wireguard) {
|
func (w *Wireguard) mergeWith(other Wireguard) {
|
||||||
w.PrivateKey = helpers.MergeWithStringPtr(w.PrivateKey, other.PrivateKey)
|
w.PrivateKey = helpers.MergeWithStringPtr(w.PrivateKey, other.PrivateKey)
|
||||||
w.PreSharedKey = helpers.MergeWithStringPtr(w.PreSharedKey, other.PreSharedKey)
|
w.PreSharedKey = helpers.MergeWithStringPtr(w.PreSharedKey, other.PreSharedKey)
|
||||||
w.Addresses = helpers.MergeIPNetsSlices(w.Addresses, other.Addresses)
|
w.Addresses = helpers.MergeNetipPrefixesSlices(w.Addresses, other.Addresses)
|
||||||
w.Interface = helpers.MergeWithString(w.Interface, other.Interface)
|
w.Interface = helpers.MergeWithString(w.Interface, other.Interface)
|
||||||
w.Implementation = helpers.MergeWithString(w.Implementation, other.Implementation)
|
w.Implementation = helpers.MergeWithString(w.Implementation, other.Implementation)
|
||||||
}
|
}
|
||||||
@ -126,7 +125,7 @@ func (w *Wireguard) mergeWith(other Wireguard) {
|
|||||||
func (w *Wireguard) overrideWith(other Wireguard) {
|
func (w *Wireguard) overrideWith(other Wireguard) {
|
||||||
w.PrivateKey = helpers.OverrideWithStringPtr(w.PrivateKey, other.PrivateKey)
|
w.PrivateKey = helpers.OverrideWithStringPtr(w.PrivateKey, other.PrivateKey)
|
||||||
w.PreSharedKey = helpers.OverrideWithStringPtr(w.PreSharedKey, other.PreSharedKey)
|
w.PreSharedKey = helpers.OverrideWithStringPtr(w.PreSharedKey, other.PreSharedKey)
|
||||||
w.Addresses = helpers.OverrideWithIPNetsSlice(w.Addresses, other.Addresses)
|
w.Addresses = helpers.OverrideWithNetipPrefixesSlice(w.Addresses, other.Addresses)
|
||||||
w.Interface = helpers.OverrideWithString(w.Interface, other.Interface)
|
w.Interface = helpers.OverrideWithString(w.Interface, other.Interface)
|
||||||
w.Implementation = helpers.OverrideWithString(w.Implementation, other.Implementation)
|
w.Implementation = helpers.OverrideWithString(w.Implementation, other.Implementation)
|
||||||
}
|
}
|
||||||
|
|||||||
14
internal/configuration/sources/env/firewall.go
vendored
14
internal/configuration/sources/env/firewall.go
vendored
@ -3,7 +3,7 @@ package env
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net/netip"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
@ -24,7 +24,7 @@ func (s *Source) readFirewall() (firewall settings.Firewall, err error) {
|
|||||||
|
|
||||||
outboundSubnetsKey, _ := s.getEnvWithRetro("FIREWALL_OUTBOUND_SUBNETS", "EXTRA_SUBNETS")
|
outboundSubnetsKey, _ := s.getEnvWithRetro("FIREWALL_OUTBOUND_SUBNETS", "EXTRA_SUBNETS")
|
||||||
outboundSubnetStrings := envToCSV(outboundSubnetsKey)
|
outboundSubnetStrings := envToCSV(outboundSubnetsKey)
|
||||||
firewall.OutboundSubnets, err = stringsToIPNets(outboundSubnetStrings)
|
firewall.OutboundSubnets, err = stringsToNetipPrefixes(outboundSubnetStrings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return firewall, fmt.Errorf("environment variable %s: %w", outboundSubnetsKey, err)
|
return firewall, fmt.Errorf("environment variable %s: %w", outboundSubnetsKey, err)
|
||||||
}
|
}
|
||||||
@ -65,18 +65,16 @@ func stringsToPorts(ss []string) (ports []uint16, err error) {
|
|||||||
return ports, nil
|
return ports, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func stringsToIPNets(ss []string) (ipNets []net.IPNet, err error) {
|
func stringsToNetipPrefixes(ss []string) (ipPrefixes []netip.Prefix, err error) {
|
||||||
if len(ss) == 0 {
|
if len(ss) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
ipNets = make([]net.IPNet, len(ss))
|
ipPrefixes = make([]netip.Prefix, len(ss))
|
||||||
for i, s := range ss {
|
for i, s := range ss {
|
||||||
ip, ipNet, err := net.ParseCIDR(s)
|
ipPrefixes[i], err = netip.ParsePrefix(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parsing IP network %q: %w", s, err)
|
return nil, fmt.Errorf("parsing IP network %q: %w", s, err)
|
||||||
}
|
}
|
||||||
ipNet.IP = ip
|
|
||||||
ipNets[i] = *ipNet
|
|
||||||
}
|
}
|
||||||
return ipNets, nil
|
return ipPrefixes, nil
|
||||||
}
|
}
|
||||||
|
|||||||
10
internal/configuration/sources/env/wireguard.go
vendored
10
internal/configuration/sources/env/wireguard.go
vendored
@ -2,7 +2,7 @@ package env
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -24,22 +24,20 @@ func (s *Source) readWireguard() (wireguard settings.Wireguard, err error) {
|
|||||||
return wireguard, nil
|
return wireguard, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Source) readWireguardAddresses() (addresses []net.IPNet, err error) {
|
func (s *Source) readWireguardAddresses() (addresses []netip.Prefix, err error) {
|
||||||
key, addressesCSV := s.getEnvWithRetro("WIREGUARD_ADDRESSES", "WIREGUARD_ADDRESS")
|
key, addressesCSV := s.getEnvWithRetro("WIREGUARD_ADDRESSES", "WIREGUARD_ADDRESS")
|
||||||
if addressesCSV == "" {
|
if addressesCSV == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
addressStrings := strings.Split(addressesCSV, ",")
|
addressStrings := strings.Split(addressesCSV, ",")
|
||||||
addresses = make([]net.IPNet, len(addressStrings))
|
addresses = make([]netip.Prefix, len(addressStrings))
|
||||||
for i, addressString := range addressStrings {
|
for i, addressString := range addressStrings {
|
||||||
addressString = strings.TrimSpace(addressString)
|
addressString = strings.TrimSpace(addressString)
|
||||||
ip, ipNet, err := net.ParseCIDR(addressString)
|
addresses[i], err = netip.ParsePrefix(addressString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
return nil, fmt.Errorf("environment variable %s: %w", key, err)
|
||||||
}
|
}
|
||||||
ipNet.IP = ip
|
|
||||||
addresses[i] = *ipNet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return addresses, nil
|
return addresses, nil
|
||||||
|
|||||||
@ -98,7 +98,7 @@ func (c *Config) enable(ctx context.Context) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, network := range c.localNetworks {
|
for _, network := range c.localNetworks {
|
||||||
if err := c.acceptOutputFromIPToSubnet(ctx, network.InterfaceName, network.IP, *network.IPNet, remove); err != nil {
|
if err := c.acceptOutputFromIPToSubnet(ctx, network.InterfaceName, network.IP, network.IPNet, remove); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = c.acceptIpv6MulticastOutput(ctx, network.InterfaceName, remove); err != nil {
|
if err = c.acceptIpv6MulticastOutput(ctx, network.InterfaceName, remove); err != nil {
|
||||||
@ -113,7 +113,7 @@ func (c *Config) enable(ctx context.Context) (err error) {
|
|||||||
// Allows packets from any IP address to go through eth0 / local network
|
// Allows packets from any IP address to go through eth0 / local network
|
||||||
// to reach Gluetun.
|
// to reach Gluetun.
|
||||||
for _, network := range c.localNetworks {
|
for _, network := range c.localNetworks {
|
||||||
if err := c.acceptInputToSubnet(ctx, network.InterfaceName, *network.IPNet, remove); err != nil {
|
if err := c.acceptInputToSubnet(ctx, network.InterfaceName, network.IPNet, remove); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package firewall
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
@ -27,7 +27,7 @@ type Config struct { //nolint:maligned
|
|||||||
enabled bool
|
enabled bool
|
||||||
vpnConnection models.Connection
|
vpnConnection models.Connection
|
||||||
vpnIntf string
|
vpnIntf string
|
||||||
outboundSubnets []net.IPNet
|
outboundSubnets []netip.Prefix
|
||||||
allowedInputPorts map[uint16]map[string]struct{} // port to interfaces set mapping
|
allowedInputPorts map[uint16]map[string]struct{} // port to interfaces set mapping
|
||||||
stateMutex sync.Mutex
|
stateMutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
@ -108,9 +109,8 @@ func (c *Config) acceptInputThroughInterface(ctx context.Context, intf string, r
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) acceptInputToSubnet(ctx context.Context, intf string, destination net.IPNet, remove bool) error {
|
func (c *Config) acceptInputToSubnet(ctx context.Context, intf string,
|
||||||
isIP4Subnet := destination.IP.To4() != nil
|
destination netip.Prefix, remove bool) error {
|
||||||
|
|
||||||
interfaceFlag := "-i " + intf
|
interfaceFlag := "-i " + intf
|
||||||
if intf == "*" { // all interfaces
|
if intf == "*" { // all interfaces
|
||||||
interfaceFlag = ""
|
interfaceFlag = ""
|
||||||
@ -119,7 +119,7 @@ func (c *Config) acceptInputToSubnet(ctx context.Context, intf string, destinati
|
|||||||
instruction := fmt.Sprintf("%s INPUT %s -d %s -j ACCEPT",
|
instruction := fmt.Sprintf("%s INPUT %s -d %s -j ACCEPT",
|
||||||
appendOrDelete(remove), interfaceFlag, destination.String())
|
appendOrDelete(remove), interfaceFlag, destination.String())
|
||||||
|
|
||||||
if isIP4Subnet {
|
if destination.Addr().Is4() {
|
||||||
return c.runIptablesInstruction(ctx, instruction)
|
return c.runIptablesInstruction(ctx, instruction)
|
||||||
}
|
}
|
||||||
if c.ip6Tables == "" {
|
if c.ip6Tables == "" {
|
||||||
@ -157,8 +157,8 @@ func (c *Config) acceptOutputTrafficToVPN(ctx context.Context,
|
|||||||
|
|
||||||
// Thanks to @npawelek.
|
// Thanks to @npawelek.
|
||||||
func (c *Config) acceptOutputFromIPToSubnet(ctx context.Context,
|
func (c *Config) acceptOutputFromIPToSubnet(ctx context.Context,
|
||||||
intf string, sourceIP net.IP, destinationSubnet net.IPNet, remove bool) error {
|
intf string, sourceIP net.IP, destinationSubnet netip.Prefix, remove bool) error {
|
||||||
doIPv4 := sourceIP.To4() != nil && destinationSubnet.IP.To4() != nil
|
doIPv4 := sourceIP.To4() != nil && destinationSubnet.Addr().Is4()
|
||||||
|
|
||||||
interfaceFlag := "-o " + intf
|
interfaceFlag := "-o " + intf
|
||||||
if intf == "*" { // all interfaces
|
if intf == "*" { // all interfaces
|
||||||
|
|||||||
@ -3,18 +3,18 @@ package firewall
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net/netip"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/subnet"
|
"github.com/qdm12/gluetun/internal/subnet"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Config) SetOutboundSubnets(ctx context.Context, subnets []net.IPNet) (err error) {
|
func (c *Config) SetOutboundSubnets(ctx context.Context, subnets []netip.Prefix) (err error) {
|
||||||
c.stateMutex.Lock()
|
c.stateMutex.Lock()
|
||||||
defer c.stateMutex.Unlock()
|
defer c.stateMutex.Unlock()
|
||||||
|
|
||||||
if !c.enabled {
|
if !c.enabled {
|
||||||
c.logger.Info("firewall disabled, only updating allowed subnets internal list")
|
c.logger.Info("firewall disabled, only updating allowed subnets internal list")
|
||||||
c.outboundSubnets = make([]net.IPNet, len(subnets))
|
c.outboundSubnets = make([]netip.Prefix, len(subnets))
|
||||||
copy(c.outboundSubnets, subnets)
|
copy(c.outboundSubnets, subnets)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ func (c *Config) SetOutboundSubnets(ctx context.Context, subnets []net.IPNet) (e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) removeOutboundSubnets(ctx context.Context, subnets []net.IPNet) {
|
func (c *Config) removeOutboundSubnets(ctx context.Context, subnets []netip.Prefix) {
|
||||||
const remove = true
|
const remove = true
|
||||||
for _, subNet := range subnets {
|
for _, subNet := range subnets {
|
||||||
for _, defaultRoute := range c.defaultRoutes {
|
for _, defaultRoute := range c.defaultRoutes {
|
||||||
@ -49,7 +49,7 @@ func (c *Config) removeOutboundSubnets(ctx context.Context, subnets []net.IPNet)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) addOutboundSubnets(ctx context.Context, subnets []net.IPNet) error {
|
func (c *Config) addOutboundSubnets(ctx context.Context, subnets []netip.Prefix) error {
|
||||||
const remove = false
|
const remove = false
|
||||||
for _, subnet := range subnets {
|
for _, subnet := range subnets {
|
||||||
for _, defaultRoute := range c.defaultRoutes {
|
for _, defaultRoute := range c.defaultRoutes {
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
package netlink
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
|
|
||||||
"github.com/vishvananda/netlink"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewIPNet(ip net.IP) *net.IPNet {
|
|
||||||
return netlink.NewIPNet(ip)
|
|
||||||
}
|
|
||||||
@ -2,6 +2,7 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
@ -25,17 +26,12 @@ func BuildWireguardSettings(connection models.Connection,
|
|||||||
copy(settings.Endpoint.IP, connection.IP)
|
copy(settings.Endpoint.IP, connection.IP)
|
||||||
settings.Endpoint.Port = int(connection.Port)
|
settings.Endpoint.Port = int(connection.Port)
|
||||||
|
|
||||||
settings.Addresses = make([]*net.IPNet, 0, len(userSettings.Addresses))
|
settings.Addresses = make([]netip.Prefix, 0, len(userSettings.Addresses))
|
||||||
for _, address := range userSettings.Addresses {
|
for _, address := range userSettings.Addresses {
|
||||||
ipv6Address := address.IP.To4() == nil
|
if !ipv6Supported && address.Addr().Is6() {
|
||||||
if !ipv6Supported && ipv6Address {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
addressCopy := new(net.IPNet)
|
addressCopy := netip.PrefixFrom(address.Addr(), address.Bits())
|
||||||
addressCopy.IP = make(net.IP, len(address.IP))
|
|
||||||
copy(addressCopy.IP, address.IP)
|
|
||||||
addressCopy.Mask = make(net.IPMask, len(address.Mask))
|
|
||||||
copy(addressCopy.Mask, address.Mask)
|
|
||||||
settings.Addresses = append(settings.Addresses, addressCopy)
|
settings.Addresses = append(settings.Addresses, addressCopy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
@ -30,9 +31,9 @@ func Test_BuildWireguardSettings(t *testing.T) {
|
|||||||
userSettings: settings.Wireguard{
|
userSettings: settings.Wireguard{
|
||||||
PrivateKey: stringPtr("private"),
|
PrivateKey: stringPtr("private"),
|
||||||
PreSharedKey: stringPtr("pre-shared"),
|
PreSharedKey: stringPtr("pre-shared"),
|
||||||
Addresses: []net.IPNet{
|
Addresses: []netip.Prefix{
|
||||||
{IP: net.IPv4(1, 1, 1, 1), Mask: net.IPv4Mask(255, 255, 255, 255)},
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 32),
|
||||||
{IP: net.IPv6zero, Mask: net.IPv4Mask(255, 255, 255, 255)},
|
netip.PrefixFrom(netip.AddrFrom16([16]byte{}), 32),
|
||||||
},
|
},
|
||||||
Interface: "wg1",
|
Interface: "wg1",
|
||||||
},
|
},
|
||||||
@ -46,8 +47,8 @@ func Test_BuildWireguardSettings(t *testing.T) {
|
|||||||
IP: net.IPv4(1, 2, 3, 4),
|
IP: net.IPv4(1, 2, 3, 4),
|
||||||
Port: 51821,
|
Port: 51821,
|
||||||
},
|
},
|
||||||
Addresses: []*net.IPNet{
|
Addresses: []netip.Prefix{
|
||||||
{IP: net.IPv4(1, 1, 1, 1), Mask: net.IPv4Mask(255, 255, 255, 255)},
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 32),
|
||||||
},
|
},
|
||||||
RulePriority: 101,
|
RulePriority: 101,
|
||||||
IPv6: boolPtr(false),
|
IPv6: boolPtr(false),
|
||||||
|
|||||||
33
internal/routing/conversion.go
Normal file
33
internal/routing/conversion.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package routing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NetipPrefixToIPNet(prefix *netip.Prefix) (ipNet *net.IPNet) {
|
||||||
|
if prefix == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
s := prefix.String()
|
||||||
|
ip, ipNet, err := net.ParseCIDR(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
ipNet.IP = ip
|
||||||
|
return ipNet
|
||||||
|
}
|
||||||
|
|
||||||
|
func netIPNetToNetipPrefix(ipNet net.IPNet) (prefix netip.Prefix) {
|
||||||
|
return netip.MustParsePrefix(ipNet.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func netIPToNetipAddress(ip net.IP) (address netip.Addr) {
|
||||||
|
address, ok := netip.AddrFromSlice(ip)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("converting %#v to netip.Addr failed", ip))
|
||||||
|
}
|
||||||
|
return address
|
||||||
|
}
|
||||||
52
internal/routing/conversion_test.go
Normal file
52
internal/routing/conversion_test.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package routing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_netIPToNetipAddress(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testCases := map[string]struct {
|
||||||
|
ip net.IP
|
||||||
|
address netip.Addr
|
||||||
|
panicMessage string
|
||||||
|
}{
|
||||||
|
"nil ip": {
|
||||||
|
panicMessage: "converting net.IP(nil) to netip.Addr failed",
|
||||||
|
},
|
||||||
|
"IPv4": {
|
||||||
|
ip: net.IPv4(1, 2, 3, 4),
|
||||||
|
address: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||||
|
},
|
||||||
|
"IPv6": {
|
||||||
|
ip: net.IPv6zero,
|
||||||
|
address: netip.AddrFrom16([16]byte{}),
|
||||||
|
},
|
||||||
|
"IPv4 prefixed with 0xffff": {
|
||||||
|
ip: net.IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 1, 2, 3, 4},
|
||||||
|
address: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, testCase := range testCases {
|
||||||
|
testCase := testCase
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
if testCase.panicMessage != "" {
|
||||||
|
assert.PanicsWithValue(t, testCase.panicMessage, func() {
|
||||||
|
netIPToNetipAddress(testCase.ip)
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
address := netIPToNetipAddress(testCase.ip)
|
||||||
|
assert.Equal(t, testCase.address, address)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@ package routing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net/netip"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/netlink"
|
"github.com/qdm12/gluetun/internal/netlink"
|
||||||
)
|
)
|
||||||
@ -17,8 +17,9 @@ func (r *Routing) routeInboundFromDefault(defaultRoutes []DefaultRoute) (err err
|
|||||||
return fmt.Errorf("adding rule: %w", err)
|
return fmt.Errorf("adding rule: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultDestinationIPv4 := net.IPNet{IP: net.IPv4(0, 0, 0, 0), Mask: net.IPv4Mask(0, 0, 0, 0)}
|
const bits = 0
|
||||||
defaultDestinationIPv6 := net.IPNet{IP: net.IPv6zero, Mask: net.IPMask(net.IPv6zero)}
|
defaultDestinationIPv4 := netip.PrefixFrom(netip.AddrFrom4([4]byte{}), bits)
|
||||||
|
defaultDestinationIPv6 := netip.PrefixFrom(netip.AddrFrom16([16]byte{}), bits)
|
||||||
|
|
||||||
for _, defaultRoute := range defaultRoutes {
|
for _, defaultRoute := range defaultRoutes {
|
||||||
defaultDestination := defaultDestinationIPv4
|
defaultDestination := defaultDestinationIPv4
|
||||||
@ -36,8 +37,9 @@ func (r *Routing) routeInboundFromDefault(defaultRoutes []DefaultRoute) (err err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Routing) unrouteInboundFromDefault(defaultRoutes []DefaultRoute) (err error) {
|
func (r *Routing) unrouteInboundFromDefault(defaultRoutes []DefaultRoute) (err error) {
|
||||||
defaultDestinationIPv4 := net.IPNet{IP: net.IPv4(0, 0, 0, 0), Mask: net.IPv4Mask(0, 0, 0, 0)}
|
const bits = 0
|
||||||
defaultDestinationIPv6 := net.IPNet{IP: net.IPv6zero, Mask: net.IPMask(net.IPv6zero)}
|
defaultDestinationIPv4 := netip.PrefixFrom(netip.AddrFrom4([4]byte{}), bits)
|
||||||
|
defaultDestinationIPv6 := netip.PrefixFrom(netip.AddrFrom16([16]byte{}), bits)
|
||||||
|
|
||||||
for _, defaultRoute := range defaultRoutes {
|
for _, defaultRoute := range defaultRoutes {
|
||||||
defaultDestination := defaultDestinationIPv4
|
defaultDestination := defaultDestinationIPv4
|
||||||
@ -60,9 +62,16 @@ func (r *Routing) unrouteInboundFromDefault(defaultRoutes []DefaultRoute) (err e
|
|||||||
|
|
||||||
func (r *Routing) addRuleInboundFromDefault(table int, defaultRoutes []DefaultRoute) (err error) {
|
func (r *Routing) addRuleInboundFromDefault(table int, defaultRoutes []DefaultRoute) (err error) {
|
||||||
for _, defaultRoute := range defaultRoutes {
|
for _, defaultRoute := range defaultRoutes {
|
||||||
defaultIPMasked32 := netlink.NewIPNet(defaultRoute.AssignedIP)
|
assignedIP := netIPToNetipAddress(defaultRoute.AssignedIP)
|
||||||
ruleDstNet := (*net.IPNet)(nil)
|
bits := 32
|
||||||
err = r.addIPRule(defaultIPMasked32, ruleDstNet, table, inboundPriority)
|
if assignedIP.Is6() {
|
||||||
|
bits = 128
|
||||||
|
}
|
||||||
|
r.logger.Debug(fmt.Sprintf("ASSIGNED IP IS %#v -> %s, bits %d",
|
||||||
|
defaultRoute.AssignedIP, assignedIP, bits))
|
||||||
|
defaultIPMasked := netip.PrefixFrom(assignedIP, bits)
|
||||||
|
ruleDstNet := (*netip.Prefix)(nil)
|
||||||
|
err = r.addIPRule(&defaultIPMasked, ruleDstNet, table, inboundPriority)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("adding rule for default route %s: %w", defaultRoute, err)
|
return fmt.Errorf("adding rule for default route %s: %w", defaultRoute, err)
|
||||||
}
|
}
|
||||||
@ -73,9 +82,14 @@ func (r *Routing) addRuleInboundFromDefault(table int, defaultRoutes []DefaultRo
|
|||||||
|
|
||||||
func (r *Routing) delRuleInboundFromDefault(table int, defaultRoutes []DefaultRoute) (err error) {
|
func (r *Routing) delRuleInboundFromDefault(table int, defaultRoutes []DefaultRoute) (err error) {
|
||||||
for _, defaultRoute := range defaultRoutes {
|
for _, defaultRoute := range defaultRoutes {
|
||||||
defaultIPMasked32 := netlink.NewIPNet(defaultRoute.AssignedIP)
|
assignedIP := netIPToNetipAddress(defaultRoute.AssignedIP)
|
||||||
ruleDstNet := (*net.IPNet)(nil)
|
bits := 32
|
||||||
err = r.deleteIPRule(defaultIPMasked32, ruleDstNet, table, inboundPriority)
|
if assignedIP.Is6() {
|
||||||
|
bits = 128
|
||||||
|
}
|
||||||
|
defaultIPMasked := netip.PrefixFrom(assignedIP, bits)
|
||||||
|
ruleDstNet := (*netip.Prefix)(nil)
|
||||||
|
err = r.deleteIPRule(&defaultIPMasked, ruleDstNet, table, inboundPriority)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("deleting rule for default route %s: %w", defaultRoute, err)
|
return fmt.Errorf("deleting rule for default route %s: %w", defaultRoute, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,18 @@ func ipMatchesFamily(ip net.IP, family int) bool {
|
|||||||
(family == netlink.FAMILY_V4 && ip.To4() != nil)
|
(family == netlink.FAMILY_V4 && ip.To4() != nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ensureNoIPv6WrappedIPv4(candidateIP net.IP) (resultIP net.IP) {
|
||||||
|
const ipv4Size = 4
|
||||||
|
if candidateIP.To4() == nil || len(candidateIP) == ipv4Size { // ipv6 or ipv4
|
||||||
|
return candidateIP
|
||||||
|
}
|
||||||
|
|
||||||
|
// ipv6-wrapped ipv4
|
||||||
|
resultIP = make(net.IP, ipv4Size)
|
||||||
|
copy(resultIP, candidateIP[12:16])
|
||||||
|
return resultIP
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Routing) assignedIP(interfaceName string, family int) (ip net.IP, err error) {
|
func (r *Routing) assignedIP(interfaceName string, family int) (ip net.IP, err error) {
|
||||||
iface, err := net.InterfaceByName(interfaceName)
|
iface, err := net.InterfaceByName(interfaceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -34,14 +46,22 @@ func (r *Routing) assignedIP(interfaceName string, family int) (ip net.IP, err e
|
|||||||
for _, address := range addresses {
|
for _, address := range addresses {
|
||||||
switch value := address.(type) {
|
switch value := address.(type) {
|
||||||
case *net.IPAddr:
|
case *net.IPAddr:
|
||||||
if ipMatchesFamily(value.IP, family) {
|
ip = value.IP
|
||||||
return value.IP, nil
|
|
||||||
}
|
|
||||||
case *net.IPNet:
|
case *net.IPNet:
|
||||||
if ipMatchesFamily(value.IP, family) {
|
ip = value.IP
|
||||||
return value.IP, nil
|
default:
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !ipMatchesFamily(ip, family) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure we don't return an IPv6-wrapped IPv4 address
|
||||||
|
// since netip.Address String method works differently than
|
||||||
|
// net.IP String method for this kind of addresses.
|
||||||
|
ip = ensureNoIPv6WrappedIPv4(ip)
|
||||||
|
return ip, nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("%w: interface %s in %d addresses",
|
return nil, fmt.Errorf("%w: interface %s in %d addresses",
|
||||||
errInterfaceIPNotFound, interfaceName, len(addresses))
|
errInterfaceIPNotFound, interfaceName, len(addresses))
|
||||||
|
|||||||
@ -96,3 +96,35 @@ func Test_IPIsPrivate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_ensureNoIPv6WrappedIPv4(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testCases := map[string]struct {
|
||||||
|
candidateIP net.IP
|
||||||
|
resultIP net.IP
|
||||||
|
}{
|
||||||
|
"nil": {},
|
||||||
|
"ipv6": {
|
||||||
|
candidateIP: net.IPv6loopback,
|
||||||
|
resultIP: net.IPv6loopback,
|
||||||
|
},
|
||||||
|
"ipv4": {
|
||||||
|
candidateIP: net.IP{1, 2, 3, 4},
|
||||||
|
resultIP: net.IP{1, 2, 3, 4},
|
||||||
|
},
|
||||||
|
"ipv6_wrapped_ipv4": {
|
||||||
|
candidateIP: net.IPv4(1, 2, 3, 4),
|
||||||
|
resultIP: net.IP{1, 2, 3, 4},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, testCase := range testCases {
|
||||||
|
testCase := testCase
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
resultIP := ensureNoIPv6WrappedIPv4(testCase.candidateIP)
|
||||||
|
assert.Equal(t, testCase.resultIP, resultIP)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/netlink"
|
"github.com/qdm12/gluetun/internal/netlink"
|
||||||
)
|
)
|
||||||
@ -15,7 +16,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type LocalNetwork struct {
|
type LocalNetwork struct {
|
||||||
IPNet *net.IPNet
|
IPNet netip.Prefix
|
||||||
InterfaceName string
|
InterfaceName string
|
||||||
IP net.IP
|
IP net.IP
|
||||||
}
|
}
|
||||||
@ -55,7 +56,7 @@ func (r *Routing) LocalNetworks() (localNetworks []LocalNetwork, err error) {
|
|||||||
|
|
||||||
var localNet LocalNetwork
|
var localNet LocalNetwork
|
||||||
|
|
||||||
localNet.IPNet = route.Dst
|
localNet.IPNet = netIPNetToNetipPrefix(*route.Dst)
|
||||||
r.logger.Info("local ipnet found: " + localNet.IPNet.String())
|
r.logger.Info("local ipnet found: " + localNet.IPNet.String())
|
||||||
|
|
||||||
link, err := r.netLinker.LinkByIndex(route.LinkIndex)
|
link, err := r.netLinker.LinkByIndex(route.LinkIndex)
|
||||||
@ -66,7 +67,7 @@ func (r *Routing) LocalNetworks() (localNetworks []LocalNetwork, err error) {
|
|||||||
localNet.InterfaceName = link.Attrs().Name
|
localNet.InterfaceName = link.Attrs().Name
|
||||||
|
|
||||||
family := netlink.FAMILY_V6
|
family := netlink.FAMILY_V6
|
||||||
if localNet.IPNet.IP.To4() != nil {
|
if localNet.IPNet.Addr().Is4() {
|
||||||
family = netlink.FAMILY_V4
|
family = netlink.FAMILY_V4
|
||||||
}
|
}
|
||||||
ip, err := r.assignedIP(localNet.InterfaceName, family)
|
ip, err := r.assignedIP(localNet.InterfaceName, family)
|
||||||
@ -87,7 +88,7 @@ func (r *Routing) LocalNetworks() (localNetworks []LocalNetwork, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Routing) AddLocalRules(subnets []LocalNetwork) (err error) {
|
func (r *Routing) AddLocalRules(subnets []LocalNetwork) (err error) {
|
||||||
for _, net := range subnets {
|
for _, subnet := range subnets {
|
||||||
// The main table is a built-in value for Linux, see "man 8 ip-route"
|
// The main table is a built-in value for Linux, see "man 8 ip-route"
|
||||||
const mainTable = 254
|
const mainTable = 254
|
||||||
|
|
||||||
@ -96,9 +97,9 @@ func (r *Routing) AddLocalRules(subnets []LocalNetwork) (err error) {
|
|||||||
const localPriority = 98
|
const localPriority = 98
|
||||||
|
|
||||||
// Main table was setup correctly by Docker, just need to add rules to use it
|
// Main table was setup correctly by Docker, just need to add rules to use it
|
||||||
err = r.addIPRule(nil, net.IPNet, mainTable, localPriority)
|
err = r.addIPRule(nil, &subnet.IPNet, mainTable, localPriority)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("adding rule: %v: %w", net.IPNet, err)
|
return fmt.Errorf("adding rule: %v: %w", subnet.IPNet, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package routing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net/netip"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/subnet"
|
"github.com/qdm12/gluetun/internal/subnet"
|
||||||
)
|
)
|
||||||
@ -12,7 +12,7 @@ const (
|
|||||||
outboundPriority = 99
|
outboundPriority = 99
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *Routing) SetOutboundRoutes(outboundSubnets []net.IPNet) error {
|
func (r *Routing) SetOutboundRoutes(outboundSubnets []netip.Prefix) error {
|
||||||
defaultRoutes, err := r.DefaultRoutes()
|
defaultRoutes, err := r.DefaultRoutes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -20,7 +20,7 @@ func (r *Routing) SetOutboundRoutes(outboundSubnets []net.IPNet) error {
|
|||||||
return r.setOutboundRoutes(outboundSubnets, defaultRoutes)
|
return r.setOutboundRoutes(outboundSubnets, defaultRoutes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Routing) setOutboundRoutes(outboundSubnets []net.IPNet,
|
func (r *Routing) setOutboundRoutes(outboundSubnets []netip.Prefix,
|
||||||
defaultRoutes []DefaultRoute) (err error) {
|
defaultRoutes []DefaultRoute) (err error) {
|
||||||
r.stateMutex.Lock()
|
r.stateMutex.Lock()
|
||||||
defer r.stateMutex.Unlock()
|
defer r.stateMutex.Unlock()
|
||||||
@ -45,7 +45,7 @@ func (r *Routing) setOutboundRoutes(outboundSubnets []net.IPNet,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Routing) removeOutboundSubnets(subnets []net.IPNet,
|
func (r *Routing) removeOutboundSubnets(subnets []netip.Prefix,
|
||||||
defaultRoutes []DefaultRoute) (warnings []string) {
|
defaultRoutes []DefaultRoute) (warnings []string) {
|
||||||
for i, subNet := range subnets {
|
for i, subNet := range subnets {
|
||||||
for _, defaultRoute := range defaultRoutes {
|
for _, defaultRoute := range defaultRoutes {
|
||||||
@ -56,7 +56,7 @@ func (r *Routing) removeOutboundSubnets(subnets []net.IPNet,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ruleSrcNet := (*net.IPNet)(nil)
|
ruleSrcNet := (*netip.Prefix)(nil)
|
||||||
ruleDstNet := &subnets[i]
|
ruleDstNet := &subnets[i]
|
||||||
err := r.deleteIPRule(ruleSrcNet, ruleDstNet, outboundTable, outboundPriority)
|
err := r.deleteIPRule(ruleSrcNet, ruleDstNet, outboundTable, outboundPriority)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -71,7 +71,7 @@ func (r *Routing) removeOutboundSubnets(subnets []net.IPNet,
|
|||||||
return warnings
|
return warnings
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Routing) addOutboundSubnets(subnets []net.IPNet,
|
func (r *Routing) addOutboundSubnets(subnets []netip.Prefix,
|
||||||
defaultRoutes []DefaultRoute) (err error) {
|
defaultRoutes []DefaultRoute) (err error) {
|
||||||
for i, subnet := range subnets {
|
for i, subnet := range subnets {
|
||||||
for _, defaultRoute := range defaultRoutes {
|
for _, defaultRoute := range defaultRoutes {
|
||||||
@ -81,7 +81,7 @@ func (r *Routing) addOutboundSubnets(subnets []net.IPNet,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ruleSrcNet := (*net.IPNet)(nil)
|
ruleSrcNet := (*netip.Prefix)(nil)
|
||||||
ruleDstNet := &subnets[i]
|
ruleDstNet := &subnets[i]
|
||||||
err = r.addIPRule(ruleSrcNet, ruleDstNet, outboundTable, outboundPriority)
|
err = r.addIPRule(ruleSrcNet, ruleDstNet, outboundTable, outboundPriority)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -3,12 +3,13 @@ package routing
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/netlink"
|
"github.com/qdm12/gluetun/internal/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *Routing) addRouteVia(destination net.IPNet, gateway net.IP,
|
func (r *Routing) addRouteVia(destination netip.Prefix, gateway net.IP,
|
||||||
iface string, table int) error {
|
iface string, table int) error {
|
||||||
destinationStr := destination.String()
|
destinationStr := destination.String()
|
||||||
r.logger.Info("adding route for " + destinationStr)
|
r.logger.Info("adding route for " + destinationStr)
|
||||||
@ -23,7 +24,7 @@ func (r *Routing) addRouteVia(destination net.IPNet, gateway net.IP,
|
|||||||
}
|
}
|
||||||
|
|
||||||
route := netlink.Route{
|
route := netlink.Route{
|
||||||
Dst: &destination,
|
Dst: NetipPrefixToIPNet(&destination),
|
||||||
Gw: gateway,
|
Gw: gateway,
|
||||||
LinkIndex: link.Attrs().Index,
|
LinkIndex: link.Attrs().Index,
|
||||||
Table: table,
|
Table: table,
|
||||||
@ -36,7 +37,7 @@ func (r *Routing) addRouteVia(destination net.IPNet, gateway net.IP,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Routing) deleteRouteVia(destination net.IPNet, gateway net.IP,
|
func (r *Routing) deleteRouteVia(destination netip.Prefix, gateway net.IP,
|
||||||
iface string, table int) (err error) {
|
iface string, table int) (err error) {
|
||||||
destinationStr := destination.String()
|
destinationStr := destination.String()
|
||||||
r.logger.Info("deleting route for " + destinationStr)
|
r.logger.Info("deleting route for " + destinationStr)
|
||||||
@ -51,7 +52,7 @@ func (r *Routing) deleteRouteVia(destination net.IPNet, gateway net.IP,
|
|||||||
}
|
}
|
||||||
|
|
||||||
route := netlink.Route{
|
route := netlink.Route{
|
||||||
Dst: &destination,
|
Dst: NetipPrefixToIPNet(&destination),
|
||||||
Gw: gateway,
|
Gw: gateway,
|
||||||
LinkIndex: link.Attrs().Index,
|
LinkIndex: link.Attrs().Index,
|
||||||
Table: table,
|
Table: table,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package routing
|
package routing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/netlink"
|
"github.com/qdm12/gluetun/internal/netlink"
|
||||||
@ -48,7 +48,7 @@ type Linker interface {
|
|||||||
type Routing struct {
|
type Routing struct {
|
||||||
netLinker NetLinker
|
netLinker NetLinker
|
||||||
logger Logger
|
logger Logger
|
||||||
outboundSubnets []net.IPNet
|
outboundSubnets []netip.Prefix
|
||||||
stateMutex sync.RWMutex
|
stateMutex sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,17 +4,18 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/netlink"
|
"github.com/qdm12/gluetun/internal/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *Routing) addIPRule(src, dst *net.IPNet, table, priority int) error {
|
func (r *Routing) addIPRule(src, dst *netip.Prefix, table, priority int) error {
|
||||||
const add = true
|
const add = true
|
||||||
r.logger.Debug(ruleDbgMsg(add, src, dst, table, priority))
|
r.logger.Debug(ruleDbgMsg(add, src, dst, table, priority))
|
||||||
|
|
||||||
rule := netlink.NewRule()
|
rule := netlink.NewRule()
|
||||||
rule.Src = src
|
rule.Src = NetipPrefixToIPNet(src)
|
||||||
rule.Dst = dst
|
rule.Dst = NetipPrefixToIPNet(dst)
|
||||||
rule.Priority = priority
|
rule.Priority = priority
|
||||||
rule.Table = table
|
rule.Table = table
|
||||||
|
|
||||||
@ -35,13 +36,13 @@ func (r *Routing) addIPRule(src, dst *net.IPNet, table, priority int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Routing) deleteIPRule(src, dst *net.IPNet, table, priority int) error {
|
func (r *Routing) deleteIPRule(src, dst *netip.Prefix, table, priority int) error {
|
||||||
const add = false
|
const add = false
|
||||||
r.logger.Debug(ruleDbgMsg(add, src, dst, table, priority))
|
r.logger.Debug(ruleDbgMsg(add, src, dst, table, priority))
|
||||||
|
|
||||||
rule := netlink.NewRule()
|
rule := netlink.NewRule()
|
||||||
rule.Src = src
|
rule.Src = NetipPrefixToIPNet(src)
|
||||||
rule.Dst = dst
|
rule.Dst = NetipPrefixToIPNet(dst)
|
||||||
rule.Priority = priority
|
rule.Priority = priority
|
||||||
rule.Table = table
|
rule.Table = table
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ func (r *Routing) deleteIPRule(src, dst *net.IPNet, table, priority int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ruleDbgMsg(add bool, src, dst *net.IPNet,
|
func ruleDbgMsg(add bool, src, dst *netip.Prefix,
|
||||||
table, priority int) (debugMessage string) {
|
table, priority int) (debugMessage string) {
|
||||||
debugMessage = "ip rule"
|
debugMessage = "ip rule"
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package routing
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
@ -11,20 +12,17 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeIPNet(t *testing.T, n byte) *net.IPNet {
|
func makeNetipPrefix(n byte) *netip.Prefix {
|
||||||
t.Helper()
|
const bits = 24
|
||||||
return &net.IPNet{
|
prefix := netip.PrefixFrom(netip.AddrFrom4([4]byte{n, n, n, 0}), bits)
|
||||||
IP: net.IPv4(n, n, n, 0),
|
return &prefix
|
||||||
Mask: net.IPv4Mask(255, 255, 255, 0),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeIPRule(t *testing.T, src, dst *net.IPNet,
|
func makeIPRule(src, dst *netip.Prefix,
|
||||||
table, priority int) *netlink.Rule {
|
table, priority int) *netlink.Rule {
|
||||||
t.Helper()
|
|
||||||
rule := netlink.NewRule()
|
rule := netlink.NewRule()
|
||||||
rule.Src = src
|
rule.Src = NetipPrefixToIPNet(src)
|
||||||
rule.Dst = dst
|
rule.Dst = NetipPrefixToIPNet(dst)
|
||||||
rule.Table = table
|
rule.Table = table
|
||||||
rule.Priority = priority
|
rule.Priority = priority
|
||||||
return rule
|
return rule
|
||||||
@ -47,8 +45,8 @@ func Test_Routing_addIPRule(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
src *net.IPNet
|
src *netip.Prefix
|
||||||
dst *net.IPNet
|
dst *netip.Prefix
|
||||||
table int
|
table int
|
||||||
priority int
|
priority int
|
||||||
dbgMsg string
|
dbgMsg string
|
||||||
@ -64,46 +62,46 @@ func Test_Routing_addIPRule(t *testing.T) {
|
|||||||
err: errors.New("listing rules: dummy error"),
|
err: errors.New("listing rules: dummy error"),
|
||||||
},
|
},
|
||||||
"rule already exists": {
|
"rule already exists": {
|
||||||
src: makeIPNet(t, 1),
|
src: makeNetipPrefix(1),
|
||||||
dst: makeIPNet(t, 2),
|
dst: makeNetipPrefix(2),
|
||||||
table: 99,
|
table: 99,
|
||||||
priority: 99,
|
priority: 99,
|
||||||
dbgMsg: "ip rule add from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
dbgMsg: "ip rule add from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
||||||
ruleList: ruleListCall{
|
ruleList: ruleListCall{
|
||||||
rules: []netlink.Rule{
|
rules: []netlink.Rule{
|
||||||
*makeIPRule(t, makeIPNet(t, 2), makeIPNet(t, 2), 99, 99),
|
*makeIPRule(makeNetipPrefix(2), makeNetipPrefix(2), 99, 99),
|
||||||
*makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 99, 99),
|
*makeIPRule(makeNetipPrefix(1), makeNetipPrefix(2), 99, 99),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"add rule error": {
|
"add rule error": {
|
||||||
src: makeIPNet(t, 1),
|
src: makeNetipPrefix(1),
|
||||||
dst: makeIPNet(t, 2),
|
dst: makeNetipPrefix(2),
|
||||||
table: 99,
|
table: 99,
|
||||||
priority: 99,
|
priority: 99,
|
||||||
dbgMsg: "ip rule add from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
dbgMsg: "ip rule add from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
||||||
ruleAdd: ruleAddCall{
|
ruleAdd: ruleAddCall{
|
||||||
expected: true,
|
expected: true,
|
||||||
ruleToAdd: makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 99, 99),
|
ruleToAdd: makeIPRule(makeNetipPrefix(1), makeNetipPrefix(2), 99, 99),
|
||||||
err: errDummy,
|
err: errDummy,
|
||||||
},
|
},
|
||||||
err: errors.New("adding rule ip rule 99: from 1.1.1.0/24 to 2.2.2.0/24 table 99: dummy error"),
|
err: errors.New("adding rule ip rule 99: from 1.1.1.0/24 to 2.2.2.0/24 table 99: dummy error"),
|
||||||
},
|
},
|
||||||
"add rule success": {
|
"add rule success": {
|
||||||
src: makeIPNet(t, 1),
|
src: makeNetipPrefix(1),
|
||||||
dst: makeIPNet(t, 2),
|
dst: makeNetipPrefix(2),
|
||||||
table: 99,
|
table: 99,
|
||||||
priority: 99,
|
priority: 99,
|
||||||
dbgMsg: "ip rule add from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
dbgMsg: "ip rule add from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
||||||
ruleList: ruleListCall{
|
ruleList: ruleListCall{
|
||||||
rules: []netlink.Rule{
|
rules: []netlink.Rule{
|
||||||
*makeIPRule(t, makeIPNet(t, 2), makeIPNet(t, 2), 99, 99),
|
*makeIPRule(makeNetipPrefix(2), makeNetipPrefix(2), 99, 99),
|
||||||
*makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 101, 101),
|
*makeIPRule(makeNetipPrefix(1), makeNetipPrefix(2), 101, 101),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ruleAdd: ruleAddCall{
|
ruleAdd: ruleAddCall{
|
||||||
expected: true,
|
expected: true,
|
||||||
ruleToAdd: makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 99, 99),
|
ruleToAdd: makeIPRule(makeNetipPrefix(1), makeNetipPrefix(2), 99, 99),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -160,8 +158,8 @@ func Test_Routing_deleteIPRule(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
src *net.IPNet
|
src *netip.Prefix
|
||||||
dst *net.IPNet
|
dst *netip.Prefix
|
||||||
table int
|
table int
|
||||||
priority int
|
priority int
|
||||||
dbgMsg string
|
dbgMsg string
|
||||||
@ -177,50 +175,50 @@ func Test_Routing_deleteIPRule(t *testing.T) {
|
|||||||
err: errors.New("listing rules: dummy error"),
|
err: errors.New("listing rules: dummy error"),
|
||||||
},
|
},
|
||||||
"rule delete error": {
|
"rule delete error": {
|
||||||
src: makeIPNet(t, 1),
|
src: makeNetipPrefix(1),
|
||||||
dst: makeIPNet(t, 2),
|
dst: makeNetipPrefix(2),
|
||||||
table: 99,
|
table: 99,
|
||||||
priority: 99,
|
priority: 99,
|
||||||
dbgMsg: "ip rule del from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
dbgMsg: "ip rule del from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
||||||
ruleList: ruleListCall{
|
ruleList: ruleListCall{
|
||||||
rules: []netlink.Rule{
|
rules: []netlink.Rule{
|
||||||
*makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 99, 99),
|
*makeIPRule(makeNetipPrefix(1), makeNetipPrefix(2), 99, 99),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ruleDel: ruleDelCall{
|
ruleDel: ruleDelCall{
|
||||||
expected: true,
|
expected: true,
|
||||||
ruleToDel: makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 99, 99),
|
ruleToDel: makeIPRule(makeNetipPrefix(1), makeNetipPrefix(2), 99, 99),
|
||||||
err: errDummy,
|
err: errDummy,
|
||||||
},
|
},
|
||||||
err: errors.New("deleting rule ip rule 99: from 1.1.1.0/24 to 2.2.2.0/24 table 99: dummy error"),
|
err: errors.New("deleting rule ip rule 99: from 1.1.1.0/24 to 2.2.2.0/24 table 99: dummy error"),
|
||||||
},
|
},
|
||||||
"rule deleted": {
|
"rule deleted": {
|
||||||
src: makeIPNet(t, 1),
|
src: makeNetipPrefix(1),
|
||||||
dst: makeIPNet(t, 2),
|
dst: makeNetipPrefix(2),
|
||||||
table: 99,
|
table: 99,
|
||||||
priority: 99,
|
priority: 99,
|
||||||
dbgMsg: "ip rule del from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
dbgMsg: "ip rule del from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
||||||
ruleList: ruleListCall{
|
ruleList: ruleListCall{
|
||||||
rules: []netlink.Rule{
|
rules: []netlink.Rule{
|
||||||
*makeIPRule(t, makeIPNet(t, 2), makeIPNet(t, 2), 99, 99),
|
*makeIPRule(makeNetipPrefix(2), makeNetipPrefix(2), 99, 99),
|
||||||
*makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 99, 99),
|
*makeIPRule(makeNetipPrefix(1), makeNetipPrefix(2), 99, 99),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ruleDel: ruleDelCall{
|
ruleDel: ruleDelCall{
|
||||||
expected: true,
|
expected: true,
|
||||||
ruleToDel: makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 99, 99),
|
ruleToDel: makeIPRule(makeNetipPrefix(1), makeNetipPrefix(2), 99, 99),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"rule does not exist": {
|
"rule does not exist": {
|
||||||
src: makeIPNet(t, 1),
|
src: makeNetipPrefix(1),
|
||||||
dst: makeIPNet(t, 2),
|
dst: makeNetipPrefix(2),
|
||||||
table: 99,
|
table: 99,
|
||||||
priority: 99,
|
priority: 99,
|
||||||
dbgMsg: "ip rule del from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
dbgMsg: "ip rule del from 1.1.1.0/24 to 2.2.2.0/24 lookup 99 pref 99",
|
||||||
ruleList: ruleListCall{
|
ruleList: ruleListCall{
|
||||||
rules: []netlink.Rule{
|
rules: []netlink.Rule{
|
||||||
*makeIPRule(t, makeIPNet(t, 2), makeIPNet(t, 2), 99, 99),
|
*makeIPRule(makeNetipPrefix(2), makeNetipPrefix(2), 99, 99),
|
||||||
*makeIPRule(t, makeIPNet(t, 1), makeIPNet(t, 2), 101, 101),
|
*makeIPRule(makeNetipPrefix(1), makeNetipPrefix(2), 101, 101),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -266,8 +264,8 @@ func Test_ruleDbgMsg(t *testing.T) {
|
|||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
add bool
|
add bool
|
||||||
src *net.IPNet
|
src *netip.Prefix
|
||||||
dst *net.IPNet
|
dst *netip.Prefix
|
||||||
table int
|
table int
|
||||||
priority int
|
priority int
|
||||||
dbgMsg string
|
dbgMsg string
|
||||||
@ -277,15 +275,15 @@ func Test_ruleDbgMsg(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"add rule": {
|
"add rule": {
|
||||||
add: true,
|
add: true,
|
||||||
src: makeIPNet(t, 1),
|
src: makeNetipPrefix(1),
|
||||||
dst: makeIPNet(t, 2),
|
dst: makeNetipPrefix(2),
|
||||||
table: 100,
|
table: 100,
|
||||||
priority: 101,
|
priority: 101,
|
||||||
dbgMsg: "ip rule add from 1.1.1.0/24 to 2.2.2.0/24 lookup 100 pref 101",
|
dbgMsg: "ip rule add from 1.1.1.0/24 to 2.2.2.0/24 lookup 100 pref 101",
|
||||||
},
|
},
|
||||||
"del rule": {
|
"del rule": {
|
||||||
src: makeIPNet(t, 1),
|
src: makeNetipPrefix(1),
|
||||||
dst: makeIPNet(t, 2),
|
dst: makeNetipPrefix(2),
|
||||||
table: 100,
|
table: 100,
|
||||||
priority: 101,
|
priority: 101,
|
||||||
dbgMsg: "ip rule del from 1.1.1.0/24 to 2.2.2.0/24 lookup 100 pref 101",
|
dbgMsg: "ip rule del from 1.1.1.0/24 to 2.2.2.0/24 lookup 100 pref 101",
|
||||||
|
|||||||
@ -1,7 +0,0 @@
|
|||||||
package subnet
|
|
||||||
|
|
||||||
import "net"
|
|
||||||
|
|
||||||
func subnetsAreEqual(a, b net.IPNet) bool {
|
|
||||||
return a.IP.Equal(b.IP) && a.Mask.String() == b.Mask.String()
|
|
||||||
}
|
|
||||||
@ -1,20 +1,20 @@
|
|||||||
package subnet
|
package subnet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net/netip"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FindSubnetsToChange(oldSubnets, newSubnets []net.IPNet) (subnetsToAdd, subnetsToRemove []net.IPNet) {
|
func FindSubnetsToChange(oldSubnets, newSubnets []netip.Prefix) (subnetsToAdd, subnetsToRemove []netip.Prefix) {
|
||||||
subnetsToAdd = findSubnetsToAdd(oldSubnets, newSubnets)
|
subnetsToAdd = findSubnetsToAdd(oldSubnets, newSubnets)
|
||||||
subnetsToRemove = findSubnetsToRemove(oldSubnets, newSubnets)
|
subnetsToRemove = findSubnetsToRemove(oldSubnets, newSubnets)
|
||||||
return subnetsToAdd, subnetsToRemove
|
return subnetsToAdd, subnetsToRemove
|
||||||
}
|
}
|
||||||
|
|
||||||
func findSubnetsToAdd(oldSubnets, newSubnets []net.IPNet) (subnetsToAdd []net.IPNet) {
|
func findSubnetsToAdd(oldSubnets, newSubnets []netip.Prefix) (subnetsToAdd []netip.Prefix) {
|
||||||
for _, newSubnet := range newSubnets {
|
for _, newSubnet := range newSubnets {
|
||||||
found := false
|
found := false
|
||||||
for _, oldSubnet := range oldSubnets {
|
for _, oldSubnet := range oldSubnets {
|
||||||
if subnetsAreEqual(oldSubnet, newSubnet) {
|
if oldSubnet.String() == newSubnet.String() {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -26,11 +26,11 @@ func findSubnetsToAdd(oldSubnets, newSubnets []net.IPNet) (subnetsToAdd []net.IP
|
|||||||
return subnetsToAdd
|
return subnetsToAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
func findSubnetsToRemove(oldSubnets, newSubnets []net.IPNet) (subnetsToRemove []net.IPNet) {
|
func findSubnetsToRemove(oldSubnets, newSubnets []netip.Prefix) (subnetsToRemove []netip.Prefix) {
|
||||||
for _, oldSubnet := range oldSubnets {
|
for _, oldSubnet := range oldSubnets {
|
||||||
found := false
|
found := false
|
||||||
for _, newSubnet := range newSubnets {
|
for _, newSubnet := range newSubnets {
|
||||||
if subnetsAreEqual(oldSubnet, newSubnet) {
|
if oldSubnet.String() == newSubnet.String() {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -42,10 +42,10 @@ func findSubnetsToRemove(oldSubnets, newSubnets []net.IPNet) (subnetsToRemove []
|
|||||||
return subnetsToRemove
|
return subnetsToRemove
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveSubnetFromSubnets(subnets []net.IPNet, subnet net.IPNet) []net.IPNet {
|
func RemoveSubnetFromSubnets(subnets []netip.Prefix, subnet netip.Prefix) []netip.Prefix {
|
||||||
L := len(subnets)
|
L := len(subnets)
|
||||||
for i := range subnets {
|
for i := range subnets {
|
||||||
if subnetsAreEqual(subnet, subnets[i]) {
|
if subnet.String() == subnets[i].String() {
|
||||||
subnets[i] = subnets[L-1]
|
subnets[i] = subnets[L-1]
|
||||||
subnets = subnets[:L-1]
|
subnets = subnets[:L-1]
|
||||||
break
|
break
|
||||||
|
|||||||
@ -2,21 +2,22 @@ package wireguard
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net/netip"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/netlink"
|
"github.com/qdm12/gluetun/internal/netlink"
|
||||||
|
"github.com/qdm12/gluetun/internal/routing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *Wireguard) addAddresses(link netlink.Link,
|
func (w *Wireguard) addAddresses(link netlink.Link,
|
||||||
addresses []*net.IPNet) (err error) {
|
addresses []netip.Prefix) (err error) {
|
||||||
for _, ipNet := range addresses {
|
for _, ipNet := range addresses {
|
||||||
ipNetIsIPv6 := ipNet.IP.To4() == nil
|
if !*w.settings.IPv6 && ipNet.Addr().Is6() {
|
||||||
if !*w.settings.IPv6 && ipNetIsIPv6 {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipNet := ipNet
|
||||||
address := &netlink.Addr{
|
address := &netlink.Addr{
|
||||||
IPNet: ipNet,
|
IPNet: routing.NetipPrefixToIPNet(&ipNet),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = w.netlink.AddrAdd(link, address)
|
err = w.netlink.AddrAdd(link, address)
|
||||||
|
|||||||
@ -2,11 +2,12 @@ package wireguard
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/qdm12/gluetun/internal/netlink"
|
"github.com/qdm12/gluetun/internal/netlink"
|
||||||
|
"github.com/qdm12/gluetun/internal/routing"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -14,8 +15,8 @@ import (
|
|||||||
func Test_Wireguard_addAddresses(t *testing.T) {
|
func Test_Wireguard_addAddresses(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
ipNetOne := &net.IPNet{IP: net.IPv4(1, 2, 3, 4), Mask: net.IPv4Mask(255, 255, 255, 255)}
|
ipNetOne := netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 2, 3, 4}), 32)
|
||||||
ipNetTwo := &net.IPNet{IP: net.ParseIP("::1234"), Mask: net.CIDRMask(64, 128)}
|
ipNetTwo := netip.PrefixFrom(netip.MustParseAddr("::1234"), 64)
|
||||||
|
|
||||||
newLink := func() netlink.Link {
|
newLink := func() netlink.Link {
|
||||||
linkAttrs := netlink.NewLinkAttrs()
|
linkAttrs := netlink.NewLinkAttrs()
|
||||||
@ -29,20 +30,20 @@ func Test_Wireguard_addAddresses(t *testing.T) {
|
|||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
link netlink.Link
|
link netlink.Link
|
||||||
addrs []*net.IPNet
|
addrs []netip.Prefix
|
||||||
wgBuilder func(ctrl *gomock.Controller, link netlink.Link) *Wireguard
|
wgBuilder func(ctrl *gomock.Controller, link netlink.Link) *Wireguard
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
"success": {
|
"success": {
|
||||||
link: newLink(),
|
link: newLink(),
|
||||||
addrs: []*net.IPNet{ipNetOne, ipNetTwo},
|
addrs: []netip.Prefix{ipNetOne, ipNetTwo},
|
||||||
wgBuilder: func(ctrl *gomock.Controller, link netlink.Link) *Wireguard {
|
wgBuilder: func(ctrl *gomock.Controller, link netlink.Link) *Wireguard {
|
||||||
netLinker := NewMockNetLinker(ctrl)
|
netLinker := NewMockNetLinker(ctrl)
|
||||||
firstCall := netLinker.EXPECT().
|
firstCall := netLinker.EXPECT().
|
||||||
AddrAdd(link, &netlink.Addr{IPNet: ipNetOne}).
|
AddrAdd(link, &netlink.Addr{IPNet: routing.NetipPrefixToIPNet(&ipNetOne)}).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
netLinker.EXPECT().
|
netLinker.EXPECT().
|
||||||
AddrAdd(link, &netlink.Addr{IPNet: ipNetTwo}).
|
AddrAdd(link, &netlink.Addr{IPNet: routing.NetipPrefixToIPNet(&ipNetTwo)}).
|
||||||
Return(nil).After(firstCall)
|
Return(nil).After(firstCall)
|
||||||
return &Wireguard{
|
return &Wireguard{
|
||||||
netlink: netLinker,
|
netlink: netLinker,
|
||||||
@ -54,11 +55,11 @@ func Test_Wireguard_addAddresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"first add error": {
|
"first add error": {
|
||||||
link: newLink(),
|
link: newLink(),
|
||||||
addrs: []*net.IPNet{ipNetOne, ipNetTwo},
|
addrs: []netip.Prefix{ipNetOne, ipNetTwo},
|
||||||
wgBuilder: func(ctrl *gomock.Controller, link netlink.Link) *Wireguard {
|
wgBuilder: func(ctrl *gomock.Controller, link netlink.Link) *Wireguard {
|
||||||
netLinker := NewMockNetLinker(ctrl)
|
netLinker := NewMockNetLinker(ctrl)
|
||||||
netLinker.EXPECT().
|
netLinker.EXPECT().
|
||||||
AddrAdd(link, &netlink.Addr{IPNet: ipNetOne}).
|
AddrAdd(link, &netlink.Addr{IPNet: routing.NetipPrefixToIPNet(&ipNetOne)}).
|
||||||
Return(errDummy)
|
Return(errDummy)
|
||||||
return &Wireguard{
|
return &Wireguard{
|
||||||
netlink: netLinker,
|
netlink: netLinker,
|
||||||
@ -71,14 +72,14 @@ func Test_Wireguard_addAddresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"second add error": {
|
"second add error": {
|
||||||
link: newLink(),
|
link: newLink(),
|
||||||
addrs: []*net.IPNet{ipNetOne, ipNetTwo},
|
addrs: []netip.Prefix{ipNetOne, ipNetTwo},
|
||||||
wgBuilder: func(ctrl *gomock.Controller, link netlink.Link) *Wireguard {
|
wgBuilder: func(ctrl *gomock.Controller, link netlink.Link) *Wireguard {
|
||||||
netLinker := NewMockNetLinker(ctrl)
|
netLinker := NewMockNetLinker(ctrl)
|
||||||
firstCall := netLinker.EXPECT().
|
firstCall := netLinker.EXPECT().
|
||||||
AddrAdd(link, &netlink.Addr{IPNet: ipNetOne}).
|
AddrAdd(link, &netlink.Addr{IPNet: routing.NetipPrefixToIPNet(&ipNetOne)}).
|
||||||
Return(nil)
|
Return(nil)
|
||||||
netLinker.EXPECT().
|
netLinker.EXPECT().
|
||||||
AddrAdd(link, &netlink.Addr{IPNet: ipNetTwo}).
|
AddrAdd(link, &netlink.Addr{IPNet: routing.NetipPrefixToIPNet(&ipNetTwo)}).
|
||||||
Return(errDummy).After(firstCall)
|
Return(errDummy).After(firstCall)
|
||||||
return &Wireguard{
|
return &Wireguard{
|
||||||
netlink: netLinker,
|
netlink: netLinker,
|
||||||
@ -91,7 +92,7 @@ func Test_Wireguard_addAddresses(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"ignore IPv6": {
|
"ignore IPv6": {
|
||||||
link: newLink(),
|
link: newLink(),
|
||||||
addrs: []*net.IPNet{ipNetTwo},
|
addrs: []netip.Prefix{ipNetTwo},
|
||||||
wgBuilder: func(ctrl *gomock.Controller, link netlink.Link) *Wireguard {
|
wgBuilder: func(ctrl *gomock.Controller, link netlink.Link) *Wireguard {
|
||||||
return &Wireguard{
|
return &Wireguard{
|
||||||
settings: Settings{
|
settings: Settings{
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package wireguard
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -33,9 +34,8 @@ func Test_New(t *testing.T) {
|
|||||||
Endpoint: &net.UDPAddr{
|
Endpoint: &net.UDPAddr{
|
||||||
IP: net.IPv4(1, 2, 3, 4),
|
IP: net.IPv4(1, 2, 3, 4),
|
||||||
},
|
},
|
||||||
Addresses: []*net.IPNet{{
|
Addresses: []netip.Prefix{
|
||||||
IP: net.IPv4(5, 6, 7, 8),
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{5, 6, 7, 8}), 32),
|
||||||
Mask: net.IPv4Mask(255, 255, 255, 255)},
|
|
||||||
},
|
},
|
||||||
FirewallMark: 100,
|
FirewallMark: 100,
|
||||||
},
|
},
|
||||||
@ -50,9 +50,8 @@ func Test_New(t *testing.T) {
|
|||||||
IP: net.IPv4(1, 2, 3, 4),
|
IP: net.IPv4(1, 2, 3, 4),
|
||||||
Port: 51820,
|
Port: 51820,
|
||||||
},
|
},
|
||||||
Addresses: []*net.IPNet{{
|
Addresses: []netip.Prefix{
|
||||||
IP: net.IPv4(5, 6, 7, 8),
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{5, 6, 7, 8}), 32),
|
||||||
Mask: net.IPv4Mask(255, 255, 255, 255)},
|
|
||||||
},
|
},
|
||||||
FirewallMark: 100,
|
FirewallMark: 100,
|
||||||
IPv6: ptr(false),
|
IPv6: ptr(false),
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ type Settings struct {
|
|||||||
Endpoint *net.UDPAddr
|
Endpoint *net.UDPAddr
|
||||||
// Addresses assigned to the client.
|
// Addresses assigned to the client.
|
||||||
// Note IPv6 addresses are ignored if IPv6 is not supported.
|
// Note IPv6 addresses are ignored if IPv6 is not supported.
|
||||||
Addresses []*net.IPNet
|
Addresses []netip.Prefix
|
||||||
// FirewallMark to be used in routing tables and IP rules.
|
// FirewallMark to be used in routing tables and IP rules.
|
||||||
// It defaults to 51820 if left to 0.
|
// It defaults to 51820 if left to 0.
|
||||||
FirewallMark int
|
FirewallMark int
|
||||||
@ -77,9 +78,7 @@ var (
|
|||||||
ErrEndpointIPMissing = errors.New("endpoint IP is missing")
|
ErrEndpointIPMissing = errors.New("endpoint IP is missing")
|
||||||
ErrEndpointPortMissing = errors.New("endpoint port is missing")
|
ErrEndpointPortMissing = errors.New("endpoint port is missing")
|
||||||
ErrAddressMissing = errors.New("interface address is missing")
|
ErrAddressMissing = errors.New("interface address is missing")
|
||||||
ErrAddressNil = errors.New("interface address is nil")
|
ErrAddressNotValid = errors.New("interface address is not valid")
|
||||||
ErrAddressIPMissing = errors.New("interface address IP is missing")
|
|
||||||
ErrAddressMaskMissing = errors.New("interface address mask is missing")
|
|
||||||
ErrFirewallMarkMissing = errors.New("firewall mark is missing")
|
ErrFirewallMarkMissing = errors.New("firewall mark is missing")
|
||||||
ErrImplementationInvalid = errors.New("invalid implementation")
|
ErrImplementationInvalid = errors.New("invalid implementation")
|
||||||
)
|
)
|
||||||
@ -122,16 +121,9 @@ func (s *Settings) Check() (err error) {
|
|||||||
return fmt.Errorf("%w", ErrAddressMissing)
|
return fmt.Errorf("%w", ErrAddressMissing)
|
||||||
}
|
}
|
||||||
for i, addr := range s.Addresses {
|
for i, addr := range s.Addresses {
|
||||||
switch {
|
if !addr.IsValid() {
|
||||||
case addr == nil:
|
|
||||||
return fmt.Errorf("%w: for address %d of %d",
|
return fmt.Errorf("%w: for address %d of %d",
|
||||||
ErrAddressNil, i+1, len(s.Addresses))
|
ErrAddressNotValid, i+1, len(s.Addresses))
|
||||||
case addr.IP == nil:
|
|
||||||
return fmt.Errorf("%w: for address %d of %d",
|
|
||||||
ErrAddressIPMissing, i+1, len(s.Addresses))
|
|
||||||
case addr.Mask == nil:
|
|
||||||
return fmt.Errorf("%w: for address %d of %d",
|
|
||||||
ErrAddressMaskMissing, i+1, len(s.Addresses))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package wireguard
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -177,7 +178,7 @@ func Test_Settings_Check(t *testing.T) {
|
|||||||
},
|
},
|
||||||
err: ErrAddressMissing,
|
err: ErrAddressMissing,
|
||||||
},
|
},
|
||||||
"nil address": {
|
"invalid address": {
|
||||||
settings: Settings{
|
settings: Settings{
|
||||||
InterfaceName: "wg0",
|
InterfaceName: "wg0",
|
||||||
PrivateKey: validKey1,
|
PrivateKey: validKey1,
|
||||||
@ -186,35 +187,9 @@ func Test_Settings_Check(t *testing.T) {
|
|||||||
IP: net.IPv4(1, 2, 3, 4),
|
IP: net.IPv4(1, 2, 3, 4),
|
||||||
Port: 51820,
|
Port: 51820,
|
||||||
},
|
},
|
||||||
Addresses: []*net.IPNet{nil},
|
Addresses: []netip.Prefix{{}},
|
||||||
},
|
},
|
||||||
err: errors.New("interface address is nil: for address 1 of 1"),
|
err: errors.New("interface address is not valid: for address 1 of 1"),
|
||||||
},
|
|
||||||
"nil address IP": {
|
|
||||||
settings: Settings{
|
|
||||||
InterfaceName: "wg0",
|
|
||||||
PrivateKey: validKey1,
|
|
||||||
PublicKey: validKey2,
|
|
||||||
Endpoint: &net.UDPAddr{
|
|
||||||
IP: net.IPv4(1, 2, 3, 4),
|
|
||||||
Port: 51820,
|
|
||||||
},
|
|
||||||
Addresses: []*net.IPNet{{}},
|
|
||||||
},
|
|
||||||
err: errors.New("interface address IP is missing: for address 1 of 1"),
|
|
||||||
},
|
|
||||||
"nil address mask": {
|
|
||||||
settings: Settings{
|
|
||||||
InterfaceName: "wg0",
|
|
||||||
PrivateKey: validKey1,
|
|
||||||
PublicKey: validKey2,
|
|
||||||
Endpoint: &net.UDPAddr{
|
|
||||||
IP: net.IPv4(1, 2, 3, 4),
|
|
||||||
Port: 51820,
|
|
||||||
},
|
|
||||||
Addresses: []*net.IPNet{{IP: net.IPv4(1, 2, 3, 4)}},
|
|
||||||
},
|
|
||||||
err: errors.New("interface address mask is missing: for address 1 of 1"),
|
|
||||||
},
|
},
|
||||||
"zero firewall mark": {
|
"zero firewall mark": {
|
||||||
settings: Settings{
|
settings: Settings{
|
||||||
@ -225,7 +200,9 @@ func Test_Settings_Check(t *testing.T) {
|
|||||||
IP: net.IPv4(1, 2, 3, 4),
|
IP: net.IPv4(1, 2, 3, 4),
|
||||||
Port: 51820,
|
Port: 51820,
|
||||||
},
|
},
|
||||||
Addresses: []*net.IPNet{{IP: net.IPv4(1, 2, 3, 4), Mask: net.CIDRMask(24, 32)}},
|
Addresses: []netip.Prefix{
|
||||||
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 2, 3, 4}), 24),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
err: ErrFirewallMarkMissing,
|
err: ErrFirewallMarkMissing,
|
||||||
},
|
},
|
||||||
@ -238,7 +215,9 @@ func Test_Settings_Check(t *testing.T) {
|
|||||||
IP: net.IPv4(1, 2, 3, 4),
|
IP: net.IPv4(1, 2, 3, 4),
|
||||||
Port: 51820,
|
Port: 51820,
|
||||||
},
|
},
|
||||||
Addresses: []*net.IPNet{{IP: net.IPv4(1, 2, 3, 4), Mask: net.CIDRMask(24, 32)}},
|
Addresses: []netip.Prefix{
|
||||||
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 2, 3, 4}), 24),
|
||||||
|
},
|
||||||
FirewallMark: 999,
|
FirewallMark: 999,
|
||||||
Implementation: "x",
|
Implementation: "x",
|
||||||
},
|
},
|
||||||
@ -253,7 +232,9 @@ func Test_Settings_Check(t *testing.T) {
|
|||||||
IP: net.IPv4(1, 2, 3, 4),
|
IP: net.IPv4(1, 2, 3, 4),
|
||||||
Port: 51820,
|
Port: 51820,
|
||||||
},
|
},
|
||||||
Addresses: []*net.IPNet{{IP: net.IPv4(1, 2, 3, 4), Mask: net.CIDRMask(24, 32)}},
|
Addresses: []netip.Prefix{
|
||||||
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 2, 3, 4}), 24),
|
||||||
|
},
|
||||||
FirewallMark: 999,
|
FirewallMark: 999,
|
||||||
Implementation: "userspace",
|
Implementation: "userspace",
|
||||||
},
|
},
|
||||||
@ -356,9 +337,9 @@ func Test_Settings_Lines(t *testing.T) {
|
|||||||
},
|
},
|
||||||
FirewallMark: 999,
|
FirewallMark: 999,
|
||||||
RulePriority: 888,
|
RulePriority: 888,
|
||||||
Addresses: []*net.IPNet{
|
Addresses: []netip.Prefix{
|
||||||
{IP: net.IPv4(1, 1, 1, 1), Mask: net.CIDRMask(24, 32)},
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 24),
|
||||||
{IP: net.IPv4(2, 2, 2, 2), Mask: net.CIDRMask(32, 32)},
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{2, 2, 2, 2}), 32),
|
||||||
},
|
},
|
||||||
IPv6: ptr(true),
|
IPv6: ptr(true),
|
||||||
Implementation: "userspace",
|
Implementation: "userspace",
|
||||||
@ -386,9 +367,9 @@ func Test_Settings_Lines(t *testing.T) {
|
|||||||
},
|
},
|
||||||
settings: Settings{
|
settings: Settings{
|
||||||
InterfaceName: "wg0",
|
InterfaceName: "wg0",
|
||||||
Addresses: []*net.IPNet{
|
Addresses: []netip.Prefix{
|
||||||
{IP: net.IPv4(1, 1, 1, 1), Mask: net.CIDRMask(24, 32)},
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 24),
|
||||||
{IP: net.IPv4(2, 2, 2, 2), Mask: net.CIDRMask(32, 32)},
|
netip.PrefixFrom(netip.AddrFrom4([4]byte{2, 2, 2, 2}), 32),
|
||||||
},
|
},
|
||||||
IPv6: ptr(false),
|
IPv6: ptr(false),
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user