2023-05-28 02:39:16 -04:00
|
|
|
package tun
|
|
|
|
|
|
|
|
import (
|
2023-05-28 05:28:10 -04:00
|
|
|
"github.com/v2fly/v2ray-core/v5/app/router/routercommon"
|
2023-05-28 02:39:16 -04:00
|
|
|
"gvisor.dev/gvisor/pkg/tcpip"
|
2023-05-28 05:28:10 -04:00
|
|
|
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
|
|
|
|
"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
|
2023-05-28 02:39:16 -04:00
|
|
|
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
|
|
|
)
|
|
|
|
|
2023-05-28 05:42:22 -04:00
|
|
|
func CreateNIC(id tcpip.NICID, linkEndpoint stack.LinkEndpoint) StackOption {
|
2023-05-28 02:39:16 -04:00
|
|
|
return func(s *stack.Stack) error {
|
2023-05-28 05:42:22 -04:00
|
|
|
if err := s.CreateNICWithOptions(id, linkEndpoint,
|
2023-05-28 02:39:16 -04:00
|
|
|
stack.NICOptions{
|
|
|
|
Disabled: false,
|
|
|
|
QDisc: nil,
|
|
|
|
}); err != nil {
|
|
|
|
return newError("failed to create NIC:", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
2023-05-28 05:28:10 -04:00
|
|
|
|
2023-05-28 05:42:22 -04:00
|
|
|
func SetPromiscuousMode(id tcpip.NICID, enable bool) StackOption {
|
|
|
|
return func(s *stack.Stack) error {
|
|
|
|
if err := s.SetPromiscuousMode(id, enable); err != nil {
|
|
|
|
return newError("failed to set promiscuous mode:", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func SetSpoofing(id tcpip.NICID, enable bool) StackOption {
|
|
|
|
return func(s *stack.Stack) error {
|
|
|
|
if err := s.SetSpoofing(id, enable); err != nil {
|
|
|
|
return newError("failed to set spoofing:", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-28 05:28:10 -04:00
|
|
|
func AddProtocolAddress(id tcpip.NICID, ips []*routercommon.CIDR) StackOption {
|
|
|
|
return func(s *stack.Stack) error {
|
|
|
|
for _, ip := range ips {
|
2023-05-28 10:43:08 -04:00
|
|
|
tcpIPAddr := tcpip.AddrFrom4Slice(ip.Ip)
|
2023-05-28 05:28:10 -04:00
|
|
|
protocolAddress := tcpip.ProtocolAddress{
|
|
|
|
AddressWithPrefix: tcpip.AddressWithPrefix{
|
2023-05-28 10:43:08 -04:00
|
|
|
Address: tcpIPAddr,
|
2023-05-28 05:28:10 -04:00
|
|
|
PrefixLen: int(ip.Prefix),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-05-28 10:43:08 -04:00
|
|
|
switch tcpIPAddr.Len() {
|
2023-05-28 05:28:10 -04:00
|
|
|
case 4:
|
|
|
|
protocolAddress.Protocol = ipv4.ProtocolNumber
|
|
|
|
case 16:
|
|
|
|
protocolAddress.Protocol = ipv6.ProtocolNumber
|
|
|
|
default:
|
2023-05-28 10:43:08 -04:00
|
|
|
return newError("invalid IP address length:", tcpIPAddr.Len())
|
2023-05-28 05:28:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := s.AddProtocolAddress(id, protocolAddress, stack.AddressProperties{}); err != nil {
|
|
|
|
return newError("failed to add protocol address:", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
2023-05-28 06:00:23 -04:00
|
|
|
|
|
|
|
func SetRouteTable(id tcpip.NICID, routes []*routercommon.CIDR) StackOption {
|
|
|
|
return func(s *stack.Stack) error {
|
|
|
|
s.SetRouteTable(func() (table []tcpip.Route) {
|
|
|
|
for _, cidrs := range routes {
|
|
|
|
subnet := tcpip.AddressWithPrefix{
|
|
|
|
Address: tcpip.AddrFrom4Slice(cidrs.Ip),
|
|
|
|
PrefixLen: int(cidrs.Prefix),
|
|
|
|
}.Subnet()
|
|
|
|
route := tcpip.Route{
|
|
|
|
Destination: subnet,
|
|
|
|
NIC: id,
|
|
|
|
}
|
|
|
|
table = append(table, route)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}())
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|