Add netns support
This commit is contained in:
parent
d0d4ebd8db
commit
994d6ccdbf
7 changed files with 220 additions and 80 deletions
95
tun_linux.go
95
tun_linux.go
|
|
@ -51,37 +51,38 @@ type NativeTun struct {
|
|||
}
|
||||
|
||||
func New(options Options) (Tun, error) {
|
||||
var nativeTun *NativeTun
|
||||
if options.FileDescriptor == 0 {
|
||||
tunFd, err := open(options.Name, options.GSO)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "open tun")
|
||||
}
|
||||
tunLink, err := netlink.LinkByName(options.Name)
|
||||
if err != nil {
|
||||
return nil, E.Errors(err, unix.Close(tunFd))
|
||||
}
|
||||
nativeTun = &NativeTun{
|
||||
tunFd: tunFd,
|
||||
tunFile: os.NewFile(uintptr(tunFd), "tun"),
|
||||
options: options,
|
||||
}
|
||||
err = nativeTun.configure(tunLink)
|
||||
if err != nil {
|
||||
return nil, E.Errors(err, unix.Close(tunFd))
|
||||
}
|
||||
} else {
|
||||
nativeTun = &NativeTun{
|
||||
tunFd: options.FileDescriptor,
|
||||
tunFile: os.NewFile(uintptr(options.FileDescriptor), "tun"),
|
||||
options: options,
|
||||
}
|
||||
if options.GSO {
|
||||
err := nativeTun.enableGSO()
|
||||
return execInNetworkNamespace(options.NetNs, func() (Tun, error) {
|
||||
tunFd, err := open(options.Name, options.GSO)
|
||||
if err != nil {
|
||||
if options.Logger != nil {
|
||||
options.Logger.Warn(err)
|
||||
}
|
||||
return nil, E.Cause(err, "open tun")
|
||||
}
|
||||
tunLink, err := netlink.LinkByName(options.Name)
|
||||
if err != nil {
|
||||
return nil, E.Errors(err, unix.Close(tunFd))
|
||||
}
|
||||
nativeTun := &NativeTun{
|
||||
tunFd: tunFd,
|
||||
tunFile: os.NewFile(uintptr(tunFd), "tun"),
|
||||
options: options,
|
||||
}
|
||||
err = nativeTun.configure(tunLink)
|
||||
if err != nil {
|
||||
return nil, E.Errors(err, unix.Close(tunFd))
|
||||
}
|
||||
return nativeTun, nil
|
||||
})
|
||||
}
|
||||
nativeTun := &NativeTun{
|
||||
tunFd: options.FileDescriptor,
|
||||
tunFile: os.NewFile(uintptr(options.FileDescriptor), "tun"),
|
||||
options: options,
|
||||
}
|
||||
if options.GSO {
|
||||
err := nativeTun.enableGSO()
|
||||
if err != nil {
|
||||
if options.Logger != nil {
|
||||
options.Logger.Warn(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -290,10 +291,10 @@ func (t *NativeTun) Name() (string, error) {
|
|||
|
||||
func (t *NativeTun) Start() error {
|
||||
if t.options.FileDescriptor == 0 {
|
||||
if !t.options.EXP_ExternalConfiguration {
|
||||
if !t.options.EXP_ExternalConfiguration && t.options.NetNs == "" {
|
||||
t.options.InterfaceMonitor.RegisterMyInterface(t.options.Name)
|
||||
}
|
||||
err := t.start()
|
||||
err := runInNetworkNamespace(t.options.NetNs, t.start)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -354,7 +355,7 @@ func (t *NativeTun) start() error {
|
|||
return E.Cause(err, "set rules")
|
||||
}
|
||||
|
||||
if t.options.DNSMode != DNSModeDisabled {
|
||||
if t.options.DNSMode != DNSModeDisabled && t.options.NetNs == "" {
|
||||
err = t.setSearchDomainForSystemdResolved()
|
||||
if err != nil {
|
||||
return E.Cause(err, "set search domain")
|
||||
|
|
@ -374,11 +375,13 @@ func (t *NativeTun) Close() error {
|
|||
if t.options.EXP_ExternalConfiguration {
|
||||
return common.Close(common.PtrOrNil(t.tunFile))
|
||||
}
|
||||
if t.options.DNSMode != DNSModeDisabled {
|
||||
if t.options.DNSMode != DNSModeDisabled && t.options.NetNs == "" {
|
||||
t.unsetSearchDomainForSystemdResolved()
|
||||
}
|
||||
t.unsetAddresses()
|
||||
return E.Errors(t.unsetRoute(), t.unsetRules(), common.Close(common.PtrOrNil(t.tunFile)))
|
||||
return E.Errors(runInNetworkNamespace(t.options.NetNs, func() error {
|
||||
t.unsetAddresses()
|
||||
return E.Errors(t.unsetRoute(), t.unsetRules())
|
||||
}), common.Close(common.PtrOrNil(t.tunFile)))
|
||||
}
|
||||
|
||||
func (t *NativeTun) Read(p []byte) (n int, err error) {
|
||||
|
|
@ -625,16 +628,18 @@ func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error {
|
|||
t.options = tunOptions
|
||||
return nil
|
||||
}
|
||||
tunLink, err := netlink.LinkByName(t.options.Name)
|
||||
if err != nil {
|
||||
return E.Cause(err, "find tun interface")
|
||||
}
|
||||
err = t.unsetRoute0(tunLink)
|
||||
if err != nil {
|
||||
return E.Cause(err, "unset old routes")
|
||||
}
|
||||
t.options = tunOptions
|
||||
return t.setRoute(tunLink)
|
||||
return runInNetworkNamespace(t.options.NetNs, func() error {
|
||||
tunLink, err := netlink.LinkByName(t.options.Name)
|
||||
if err != nil {
|
||||
return E.Cause(err, "find tun interface")
|
||||
}
|
||||
err = t.unsetRoute0(tunLink)
|
||||
if err != nil {
|
||||
return E.Cause(err, "unset old routes")
|
||||
}
|
||||
t.options = tunOptions
|
||||
return t.setRoute(tunLink)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *NativeTun) routes(tunLink netlink.Link) ([]netlink.Route, error) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue