@@ -41,6 +41,7 @@ import (
41
41
"tailscale.com/syncs"
42
42
"tailscale.com/types/logger"
43
43
"tailscale.com/types/netmap"
44
+ "tailscale.com/version/distro"
44
45
"tailscale.com/wgengine"
45
46
"tailscale.com/wgengine/filter"
46
47
"tailscale.com/wgengine/magicsock"
@@ -394,8 +395,14 @@ func (ns *Impl) shouldProcessInbound(p *packet.Parsed, t *tstun.Wrapper) bool {
394
395
return false
395
396
}
396
397
398
+ // setAmbientCapsRaw is non-nil on Linux for Synology, to run ping with
399
+ // CAP_NET_RAW from tailscaled's binary.
400
+ var setAmbientCapsRaw func (* exec.Cmd )
401
+
397
402
var userPingSem = syncs .NewSemaphore (20 ) // 20 child ping processes at once
398
403
404
+ var isSynology = runtime .GOOS == "linux" && distro .Get () == distro .Synology
405
+
399
406
// userPing tried to ping dstIP and if it succeeds, injects pingResPkt
400
407
// into the tundev.
401
408
//
@@ -426,11 +433,21 @@ func (ns *Impl) userPing(dstIP netaddr.IP, pingResPkt []byte) {
426
433
}
427
434
err = exec .Command (ping , "-c" , "1" , "-w" , "3" , dstIP .String ()).Run ()
428
435
default :
429
- err = exec .Command ("ping" , "-c" , "1" , "-W" , "3" , dstIP .String ()).Run ()
436
+ ping := "ping"
437
+ if isSynology {
438
+ ping = "/bin/ping"
439
+ }
440
+ cmd := exec .Command (ping , "-c" , "1" , "-W" , "3" , dstIP .String ())
441
+ if isSynology && os .Getuid () != 0 {
442
+ // On DSM7 we run as non-root and need to pass
443
+ // CAP_NET_RAW if our binary has it.
444
+ setAmbientCapsRaw (cmd )
445
+ }
446
+ err = cmd .Run ()
430
447
}
431
448
d := time .Since (t0 )
432
449
if err != nil {
433
- ns .logf ("exec ping of %v failed in %v" , dstIP , d )
450
+ ns .logf ("exec ping of %v failed in %v: %v " , dstIP , d , err )
434
451
return
435
452
}
436
453
if debugNetstack {
0 commit comments