|
@@ -34,10 +34,11 @@ type tun struct {
|
|
|
deviceIndex int
|
|
|
ioctlFd uintptr
|
|
|
|
|
|
- Routes atomic.Pointer[[]Route]
|
|
|
- routeTree atomic.Pointer[bart.Table[routing.Gateways]]
|
|
|
- routeChan chan struct{}
|
|
|
- useSystemRoutes bool
|
|
|
+ Routes atomic.Pointer[[]Route]
|
|
|
+ routeTree atomic.Pointer[bart.Table[routing.Gateways]]
|
|
|
+ routeChan chan struct{}
|
|
|
+ useSystemRoutes bool
|
|
|
+ useSystemRoutesBufferSize int
|
|
|
|
|
|
l *logrus.Logger
|
|
|
}
|
|
@@ -124,12 +125,13 @@ func newTun(c *config.C, l *logrus.Logger, vpnNetworks []netip.Prefix, multiqueu
|
|
|
|
|
|
func newTunGeneric(c *config.C, l *logrus.Logger, file *os.File, vpnNetworks []netip.Prefix) (*tun, error) {
|
|
|
t := &tun{
|
|
|
- ReadWriteCloser: file,
|
|
|
- fd: int(file.Fd()),
|
|
|
- vpnNetworks: vpnNetworks,
|
|
|
- TXQueueLen: c.GetInt("tun.tx_queue", 500),
|
|
|
- useSystemRoutes: c.GetBool("tun.use_system_route_table", false),
|
|
|
- l: l,
|
|
|
+ ReadWriteCloser: file,
|
|
|
+ fd: int(file.Fd()),
|
|
|
+ vpnNetworks: vpnNetworks,
|
|
|
+ TXQueueLen: c.GetInt("tun.tx_queue", 500),
|
|
|
+ useSystemRoutes: c.GetBool("tun.use_system_route_table", false),
|
|
|
+ useSystemRoutesBufferSize: c.GetInt("tun.use_system_route_table_buffer_size", 0),
|
|
|
+ l: l,
|
|
|
}
|
|
|
|
|
|
err := t.reload(c, true)
|
|
@@ -531,7 +533,13 @@ func (t *tun) watchRoutes() {
|
|
|
rch := make(chan netlink.RouteUpdate)
|
|
|
doneChan := make(chan struct{})
|
|
|
|
|
|
- if err := netlink.RouteSubscribe(rch, doneChan); err != nil {
|
|
|
+ netlinkOptions := netlink.RouteSubscribeOptions{
|
|
|
+ ReceiveBufferSize: t.useSystemRoutesBufferSize,
|
|
|
+ ReceiveBufferForceSize: t.useSystemRoutesBufferSize != 0,
|
|
|
+ ErrorCallback: func(e error) { t.l.WithError(e).Errorf("netlink error") },
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := netlink.RouteSubscribeWithOptions(rch, doneChan, netlinkOptions); err != nil {
|
|
|
t.l.WithError(err).Errorf("failed to subscribe to system route changes")
|
|
|
return
|
|
|
}
|
|
@@ -541,8 +549,14 @@ func (t *tun) watchRoutes() {
|
|
|
go func() {
|
|
|
for {
|
|
|
select {
|
|
|
- case r := <-rch:
|
|
|
- t.updateRoutes(r)
|
|
|
+ case r, ok := <-rch:
|
|
|
+ if ok {
|
|
|
+ t.updateRoutes(r)
|
|
|
+ } else {
|
|
|
+ // may be should do something here as
|
|
|
+ // netlink stops sending updates
|
|
|
+ return
|
|
|
+ }
|
|
|
case <-doneChan:
|
|
|
// netlink.RouteSubscriber will close the rch for us
|
|
|
return
|