From 0a246fab80581351309cdfe39ffeeffa00f811b1 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Wed, 31 Jul 2019 20:29:07 -0700 Subject: Basic support for 'ip route' Implements support for RTM_GETROUTE requests for netlink sockets. Fixes #507 PiperOrigin-RevId: 261051045 --- pkg/sentry/socket/epsocket/epsocket.go | 8 +++--- pkg/sentry/socket/epsocket/stack.go | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) (limited to 'pkg/sentry/socket/epsocket') diff --git a/pkg/sentry/socket/epsocket/epsocket.go b/pkg/sentry/socket/epsocket/epsocket.go index e57aed927..0f483faa8 100644 --- a/pkg/sentry/socket/epsocket/epsocket.go +++ b/pkg/sentry/socket/epsocket/epsocket.go @@ -2252,19 +2252,19 @@ func interfaceIoctl(ctx context.Context, io usermem.IO, arg int, ifr *linux.IFRe case syscall.SIOCGIFMAP: // Gets the hardware parameters of the device. - // TODO(b/71872867): Implement. + // TODO(gvisor.dev/issue/505): Implement. case syscall.SIOCGIFTXQLEN: // Gets the transmit queue length of the device. - // TODO(b/71872867): Implement. + // TODO(gvisor.dev/issue/505): Implement. case syscall.SIOCGIFDSTADDR: // Gets the destination address of a point-to-point device. - // TODO(b/71872867): Implement. + // TODO(gvisor.dev/issue/505): Implement. case syscall.SIOCGIFBRDADDR: // Gets the broadcast address of a device. - // TODO(b/71872867): Implement. + // TODO(gvisor.dev/issue/505): Implement. case syscall.SIOCGIFNETMASK: // Gets the network mask of a device. diff --git a/pkg/sentry/socket/epsocket/stack.go b/pkg/sentry/socket/epsocket/stack.go index 8fe489c0e..27774be33 100644 --- a/pkg/sentry/socket/epsocket/stack.go +++ b/pkg/sentry/socket/epsocket/stack.go @@ -19,6 +19,8 @@ import ( "gvisor.dev/gvisor/pkg/log" "gvisor.dev/gvisor/pkg/sentry/inet" "gvisor.dev/gvisor/pkg/syserr" + "gvisor.dev/gvisor/pkg/tcpip" + "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/network/ipv4" "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" "gvisor.dev/gvisor/pkg/tcpip/stack" @@ -143,3 +145,46 @@ func (s *Stack) SetTCPSACKEnabled(enabled bool) error { func (s *Stack) Statistics(stat interface{}, arg string) error { return syserr.ErrEndpointOperation.ToError() } + +// RouteTable implements inet.Stack.RouteTable. +func (s *Stack) RouteTable() []inet.Route { + var routeTable []inet.Route + + for _, rt := range s.Stack.GetRouteTable() { + var family uint8 + switch len(rt.Destination) { + case header.IPv4AddressSize: + family = linux.AF_INET + case header.IPv6AddressSize: + family = linux.AF_INET6 + default: + log.Warningf("Unknown network protocol in route %+v", rt) + continue + } + + dstSubnet, err := tcpip.NewSubnet(rt.Destination, rt.Mask) + if err != nil { + log.Warningf("Invalid destination & mask in route: %s(%s): %v", rt.Destination, rt.Mask, err) + continue + } + routeTable = append(routeTable, inet.Route{ + Family: family, + DstLen: uint8(dstSubnet.Prefix()), // The CIDR prefix for the destination. + + // Always return unspecified protocol since we have no notion of + // protocol for routes. + Protocol: linux.RTPROT_UNSPEC, + // Set statically to LINK scope for now. + // + // TODO(gvisor.dev/issue/595): Set scope for routes. + Scope: linux.RT_SCOPE_LINK, + Type: linux.RTN_UNICAST, + + DstAddr: []byte(rt.Destination), + OutputInterface: int32(rt.NIC), + GatewayAddr: []byte(rt.Gateway), + }) + } + + return routeTable +} -- cgit v1.2.3