Files
openp2p/core/optun_linux.go
T
TenderIronh 12393f00c5 v3.25.8
2026-04-01 15:33:30 +08:00

139 lines
2.8 KiB
Go

//go:build !android
// +build !android
// optun_linux.go
package openp2p
import (
"fmt"
"net"
"os"
"github.com/openp2p-cn/wireguard-go/tun"
"github.com/vishvananda/netlink"
)
const (
tunIfaceName = "optun"
PIHeaderSize = 0
// sdwan
ReadTunBuffSize = 2048
ReadTunBuffNum = 16
)
var previousIP = ""
func (t *optun) Start(localAddr string, detail *SDWANInfo) error {
var err error
t.tunName = tunIfaceName
t.dev, err = tun.CreateTUN(t.tunName, int(detail.Mtu))
if err != nil {
return err
}
err = os.WriteFile("/proc/sys/net/ipv4/ip_forward", []byte("1"), 0644)
if err != nil {
gLog.e("write ip_forward error:%s", err)
}
return nil
}
func (t *optun) Read(bufs [][]byte, sizes []int, offset int) (n int, err error) {
return t.dev.Read(bufs, sizes, offset)
}
func (t *optun) Write(bufs [][]byte, offset int) (int, error) {
return t.dev.Write(bufs, offset)
}
func setTunAddr(ifname, localAddr, remoteAddr string, wintun interface{}) error {
ifce, err := netlink.LinkByName(ifname)
if err != nil {
return err
}
netlink.LinkSetMTU(ifce, int(gConf.getSDWAN().Mtu))
netlink.LinkSetTxQLen(ifce, 1000)
netlink.LinkSetUp(ifce)
ln, err := netlink.ParseIPNet(localAddr)
if err != nil {
return err
}
ln.Mask = net.CIDRMask(32, 32)
rn, err := netlink.ParseIPNet(remoteAddr)
if err != nil {
return err
}
rn.Mask = net.CIDRMask(32, 32)
addr := &netlink.Addr{
IPNet: ln,
Peer: rn,
}
if previousIP != "" {
lnDel, err := netlink.ParseIPNet(previousIP)
if err != nil {
return err
}
lnDel.Mask = net.CIDRMask(32, 32)
addrDel := &netlink.Addr{
IPNet: lnDel,
Peer: rn,
}
netlink.AddrDel(ifce, addrDel)
}
previousIP = localAddr
return netlink.AddrAdd(ifce, addr)
}
func addRoute(dst, gw, ifname string) error {
_, networkid, err := net.ParseCIDR(dst)
if err != nil {
return err
}
ipGW := net.ParseIP(gw)
if ipGW == nil {
return fmt.Errorf("parse gateway %s failed", gw)
}
route := &netlink.Route{
Dst: networkid,
Gw: ipGW,
}
return netlink.RouteAdd(route)
}
func delRoute(dst, gw string) error {
_, networkid, err := net.ParseCIDR(dst)
if err != nil {
return err
}
route := &netlink.Route{
Dst: networkid,
}
return netlink.RouteDel(route)
}
func delRoutesByGateway(gateway string) error {
ipGW := net.ParseIP(gateway)
if ipGW == nil {
return fmt.Errorf("invalid gateway IP: %s", gateway)
}
routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
if err != nil {
return fmt.Errorf("failed to list routes: %v", err)
}
for _, route := range routes {
if route.Gw != nil && route.Gw.Equal(ipGW) || (route.Dst != nil && route.Dst.IP.Equal(ipGW)) {
err := netlink.RouteDel(&route)
if err != nil {
gLog.e("Failed to delete route: %v, error: %v", route, err)
continue
}
gLog.i("Deleted route: %v", route)
}
}
return nil
}