You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: vpn.go
    path of file: ./repos/gluetun/internal/routing
    
    the code of the file until where you have to start completion: package routing

import (
	"errors"
	"fmt"
	"net/netip"

	"github.com/qdm12/gluetun/internal/netlink"
	"golang.org/x/sys/unix"
)

var (
	ErrVPNLocalGatewayIPNotFound       = errors.New("VPN local gateway IP address not found")
	ErrVPNLocalGatewayIPv6NotSupported = errors.New("VPN local gateway IPv6 address not supported")
)

func (r *Routing) VPNLocalGatewayIP(vpnIntf string) (ip netip.Addr, err error) {
	vpnLink, err := r.netLinker.LinkByName(vpnIntf)
	
    
func (r *Routing) VPNLocalGatewayIP(vpnIntf string) (ip netip.Addr, err error) {
	vpnLink, err := r.netLinker.LinkByName(vpnIntf)
	if err != nil {
		return ip, fmt.Errorf("finding link %s: %w", vpnIntf, err)
	}
	vpnLinkIndex := vpnLink.Index

	routes, err := r.netLinker.RouteList(netlink.FamilyAll)
	if err != nil {
		return ip, fmt.Errorf("listing routes: %w", err)
	}
	for _, route := range routes {
		if route.LinkIndex != vpnLinkIndex {
			continue
		}

		switch {
		case route.Dst.IsValid() && route.Dst.Addr().IsUnspecified(): // OpenVPN
			return route.Gw, nil
		case route.Dst.IsSingleIP() &&
			route.Dst.Addr().Compare(route.Src) == 0 &&
			route.Table == unix.RT_TABLE_LOCAL: // Wireguard
			route.Src = route.Src.Unmap()
			if route.Src.Is6() {
				return netip.Addr{}, fmt.Errorf("%w: %s", ErrVPNLocalGatewayIPv6NotSupported, route.Src)
			}
			bytes := route.Src.As4()
			// force last byte to 1 to get the VPN gateway IP
			// This is not necessarily bullet proof but it seems to work.
			bytes[3] = 1
			return netip.AddrFrom4(bytes), nil
		}
	}
	return ip, fmt.Errorf("%w: in %d routes", ErrVPNLocalGatewayIPNotFound, len(routes))
}