From 705605f9011cfbd58f407ca84bc4c2d8cf39d80b Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Tue, 22 May 2018 13:46:37 -0700 Subject: 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 --- pkg/sentry/socket/epsocket/epsocket.go | 57 ++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) (limited to 'pkg/sentry/socket') 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 +} -- cgit v1.2.3