summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/socket/epsocket
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2018-05-22 13:46:37 -0700
committerShentubot <shentubot@google.com>2018-05-22 13:47:33 -0700
commit705605f9011cfbd58f407ca84bc4c2d8cf39d80b (patch)
treee08ede03814f377f2fa7421b6a724a62b601637a /pkg/sentry/socket/epsocket
parent3a6070dc9882d43b00bd66b23492daa422435c7c (diff)
sentry: Add simple SIOCGIFFLAGS support (IFF_RUNNING and IFF_PROMIS).
Establishes a way of communicating interface flags between netstack and epsocket. More flags can be added over time. PiperOrigin-RevId: 197616669 Change-Id: I230448c5fb5b7d2e8d69b41a451eb4e1096a0e30
Diffstat (limited to 'pkg/sentry/socket/epsocket')
-rw-r--r--pkg/sentry/socket/epsocket/epsocket.go57
1 files changed, 54 insertions, 3 deletions
diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go
index 2495ba459..9ff9af0bc 100644
--- a/pkg/sentry/socket/epsocket/epsocket.go
+++ b/pkg/sentry/socket/epsocket/epsocket.go
@@ -48,12 +48,15 @@ import (
"gvisor.googlesource.com/gvisor/pkg/syserror"
"gvisor.googlesource.com/gvisor/pkg/tcpip"
"gvisor.googlesource.com/gvisor/pkg/tcpip/buffer"
+ nstack "gvisor.googlesource.com/gvisor/pkg/tcpip/stack"
"gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix"
"gvisor.googlesource.com/gvisor/pkg/waiter"
)
const sizeOfInt32 int = 4
+var errStackType = syserr.New("expected but did not receive an epsocket.Stack", linux.EINVAL)
+
// ntohs converts a 16-bit number from network byte order to host byte order. It
// assumes that the host is little endian.
func ntohs(v uint16) uint16 {
@@ -1177,9 +1180,11 @@ func interfaceIoctl(ctx context.Context, io usermem.IO, arg int, ifr *linux.IFRe
usermem.ByteOrder.PutUint16(ifr.Data[:2], uint16(n))
case syscall.SIOCGIFFLAGS:
- // TODO: Implement. For now, return only that the
- // device is up so that ifconfig prints it.
- usermem.ByteOrder.PutUint16(ifr.Data[:2], linux.IFF_UP)
+ f, err := interfaceStatusFlags(stack, iface.Name)
+ if err != nil {
+ return err
+ }
+ usermem.ByteOrder.PutUint16(ifr.Data[:2], f)
case syscall.SIOCGIFADDR:
// Copy the IPv4 address out.
@@ -1288,3 +1293,49 @@ func ifconfIoctl(ctx context.Context, io usermem.IO, ifc *linux.IFConf) error {
}
return nil
}
+
+// interfaceStatusFlags returns status flags for an interface in the stack.
+// Flag values and meanings are described in greater detail in netdevice(7) in
+// the SIOCGIFFLAGS section.
+func interfaceStatusFlags(stack inet.Stack, name string) (uint16, *syserr.Error) {
+ // epsocket should only ever be passed an epsocket.Stack.
+ epstack, ok := stack.(*Stack)
+ if !ok {
+ return 0, errStackType
+ }
+
+ // Find the NIC corresponding to this interface.
+ var (
+ nicid tcpip.NICID
+ info nstack.NICInfo
+ found bool
+ )
+ ns := epstack.Stack
+ for nicid, info = range ns.NICInfo() {
+ if info.Name == name {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return 0, syserr.ErrNoDevice
+ }
+
+ // Set flags based on NIC state.
+ nicFlags, err := ns.NICFlags(nicid)
+ if err != nil {
+ return 0, syserr.TranslateNetstackError(err)
+ }
+
+ var retFlags uint16
+ if nicFlags.Up {
+ retFlags |= linux.IFF_UP
+ }
+ if nicFlags.Running {
+ retFlags |= linux.IFF_RUNNING
+ }
+ if nicFlags.Promiscuous {
+ retFlags |= linux.IFF_PROMISC
+ }
+ return retFlags, nil
+}