gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/socket/netstack/stack.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package netstack
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"gvisor.dev/gvisor/pkg/abi/linux"
    21  	"gvisor.dev/gvisor/pkg/context"
    22  	"gvisor.dev/gvisor/pkg/errors/linuxerr"
    23  	"gvisor.dev/gvisor/pkg/log"
    24  	"gvisor.dev/gvisor/pkg/refs"
    25  	"gvisor.dev/gvisor/pkg/sentry/inet"
    26  	"gvisor.dev/gvisor/pkg/sentry/socket/netlink/nlmsg"
    27  	"gvisor.dev/gvisor/pkg/syserr"
    28  	"gvisor.dev/gvisor/pkg/tcpip"
    29  	"gvisor.dev/gvisor/pkg/tcpip/header"
    30  	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
    31  	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
    32  	"gvisor.dev/gvisor/pkg/tcpip/stack"
    33  	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
    34  )
    35  
    36  // Stack implements inet.Stack for netstack/tcpip/stack.Stack.
    37  //
    38  // +stateify savable
    39  type Stack struct {
    40  	Stack *stack.Stack `state:"manual"`
    41  }
    42  
    43  // Destroy implements inet.Stack.Destroy.
    44  func (s *Stack) Destroy() {
    45  	s.Stack.Close()
    46  	refs.CleanupSync.Add(1)
    47  	go func() {
    48  		s.Stack.Wait()
    49  		refs.CleanupSync.Done()
    50  	}()
    51  }
    52  
    53  // SupportsIPv6 implements Stack.SupportsIPv6.
    54  func (s *Stack) SupportsIPv6() bool {
    55  	return s.Stack.CheckNetworkProtocol(ipv6.ProtocolNumber)
    56  }
    57  
    58  // Converts Netstack's ARPHardwareType to equivalent linux constants.
    59  func toLinuxARPHardwareType(t header.ARPHardwareType) uint16 {
    60  	switch t {
    61  	case header.ARPHardwareNone:
    62  		return linux.ARPHRD_NONE
    63  	case header.ARPHardwareLoopback:
    64  		return linux.ARPHRD_LOOPBACK
    65  	case header.ARPHardwareEther:
    66  		return linux.ARPHRD_ETHER
    67  	default:
    68  		panic(fmt.Sprintf("unknown ARPHRD type: %d", t))
    69  	}
    70  }
    71  
    72  // Interfaces implements inet.Stack.Interfaces.
    73  func (s *Stack) Interfaces() map[int32]inet.Interface {
    74  	is := make(map[int32]inet.Interface)
    75  	for id, ni := range s.Stack.NICInfo() {
    76  		is[int32(id)] = inet.Interface{
    77  			Name:       ni.Name,
    78  			Addr:       []byte(ni.LinkAddress),
    79  			Flags:      uint32(nicStateFlagsToLinux(ni.Flags)),
    80  			DeviceType: toLinuxARPHardwareType(ni.ARPHardwareType),
    81  			MTU:        ni.MTU,
    82  		}
    83  	}
    84  	return is
    85  }
    86  
    87  // RemoveInterface implements inet.Stack.RemoveInterface.
    88  func (s *Stack) RemoveInterface(idx int32) error {
    89  	nic := tcpip.NICID(idx)
    90  
    91  	nicInfo, ok := s.Stack.NICInfo()[nic]
    92  	if !ok {
    93  		return syserr.ErrUnknownNICID.ToError()
    94  	}
    95  
    96  	// Don't allow removing the loopback interface.
    97  	if nicInfo.Flags.Loopback {
    98  		return syserr.ErrNotSupported.ToError()
    99  	}
   100  
   101  	return syserr.TranslateNetstackError(s.Stack.RemoveNIC(nic)).ToError()
   102  }
   103  
   104  // SetInterface implements inet.Stack.SetInterface.
   105  func (s *Stack) SetInterface(ctx context.Context, msg *nlmsg.Message) *syserr.Error {
   106  	var ifinfomsg linux.InterfaceInfoMessage
   107  	attrs, ok := msg.GetData(&ifinfomsg)
   108  	if !ok {
   109  		return syserr.ErrInvalidArgument
   110  	}
   111  	for !attrs.Empty() {
   112  		// The index is unspecified, search by the interface name.
   113  		ahdr, value, rest, ok := attrs.ParseFirst()
   114  		if !ok {
   115  			return syserr.ErrInvalidArgument
   116  		}
   117  		attrs = rest
   118  		switch ahdr.Type {
   119  		case linux.IFLA_IFNAME:
   120  			if len(value) < 1 {
   121  				return syserr.ErrInvalidArgument
   122  			}
   123  			if ifinfomsg.Index != 0 {
   124  				// Device name changing isn't supported yet.
   125  				return syserr.ErrNotSupported
   126  			}
   127  			ifname := string(value[:len(value)-1])
   128  			for idx, ifa := range s.Interfaces() {
   129  				if ifname == ifa.Name {
   130  					ifinfomsg.Index = idx
   131  					break
   132  				}
   133  			}
   134  		default:
   135  			ctx.Warningf("unexpected attribute: %x", ahdr.Type)
   136  			return syserr.ErrNotSupported
   137  		}
   138  	}
   139  	if ifinfomsg.Index == 0 {
   140  		return syserr.ErrNoDevice
   141  	}
   142  
   143  	flags := msg.Header().Flags
   144  	if flags&(linux.NLM_F_EXCL|linux.NLM_F_REPLACE) != 0 {
   145  		return syserr.ErrExists
   146  	}
   147  
   148  	if ifinfomsg.Flags != 0 || ifinfomsg.Change != 0 {
   149  		if ifinfomsg.Change & ^uint32(linux.IFF_UP) != 0 {
   150  			ctx.Warningf("Unsupported ifi_change flags: %x", ifinfomsg.Change)
   151  			return syserr.ErrInvalidArgument
   152  		}
   153  		if ifinfomsg.Flags & ^uint32(linux.IFF_UP) != 0 {
   154  			ctx.Warningf("Unsupported ifi_flags: %x", ifinfomsg.Change)
   155  			return syserr.ErrInvalidArgument
   156  		}
   157  		// Netstack interfaces are always up.
   158  	}
   159  	return nil
   160  }
   161  
   162  // InterfaceAddrs implements inet.Stack.InterfaceAddrs.
   163  func (s *Stack) InterfaceAddrs() map[int32][]inet.InterfaceAddr {
   164  	nicAddrs := make(map[int32][]inet.InterfaceAddr)
   165  	for id, ni := range s.Stack.NICInfo() {
   166  		var addrs []inet.InterfaceAddr
   167  		for _, a := range ni.ProtocolAddresses {
   168  			var family uint8
   169  			switch a.Protocol {
   170  			case ipv4.ProtocolNumber:
   171  				family = linux.AF_INET
   172  			case ipv6.ProtocolNumber:
   173  				family = linux.AF_INET6
   174  			default:
   175  				log.Warningf("Unknown network protocol in %+v", a)
   176  				continue
   177  			}
   178  
   179  			addrCopy := a.AddressWithPrefix.Address
   180  			addrs = append(addrs, inet.InterfaceAddr{
   181  				Family:    family,
   182  				PrefixLen: uint8(a.AddressWithPrefix.PrefixLen),
   183  				Addr:      addrCopy.AsSlice(),
   184  				// TODO(b/68878065): Other fields.
   185  			})
   186  		}
   187  		nicAddrs[int32(id)] = addrs
   188  	}
   189  	return nicAddrs
   190  }
   191  
   192  // convertAddr converts an InterfaceAddr to a ProtocolAddress.
   193  func convertAddr(addr inet.InterfaceAddr) (tcpip.ProtocolAddress, error) {
   194  	var (
   195  		protocol        tcpip.NetworkProtocolNumber
   196  		address         tcpip.Address
   197  		protocolAddress tcpip.ProtocolAddress
   198  	)
   199  	switch addr.Family {
   200  	case linux.AF_INET:
   201  		if len(addr.Addr) != header.IPv4AddressSize {
   202  			return protocolAddress, linuxerr.EINVAL
   203  		}
   204  		if addr.PrefixLen > header.IPv4AddressSize*8 {
   205  			return protocolAddress, linuxerr.EINVAL
   206  		}
   207  		protocol = ipv4.ProtocolNumber
   208  		address = tcpip.AddrFrom4Slice(addr.Addr)
   209  	case linux.AF_INET6:
   210  		if len(addr.Addr) != header.IPv6AddressSize {
   211  			return protocolAddress, linuxerr.EINVAL
   212  		}
   213  		if addr.PrefixLen > header.IPv6AddressSize*8 {
   214  			return protocolAddress, linuxerr.EINVAL
   215  		}
   216  		protocol = ipv6.ProtocolNumber
   217  		address = tcpip.AddrFrom16Slice(addr.Addr)
   218  	default:
   219  		return protocolAddress, linuxerr.ENOTSUP
   220  	}
   221  
   222  	protocolAddress = tcpip.ProtocolAddress{
   223  		Protocol: protocol,
   224  		AddressWithPrefix: tcpip.AddressWithPrefix{
   225  			Address:   address,
   226  			PrefixLen: int(addr.PrefixLen),
   227  		},
   228  	}
   229  	return protocolAddress, nil
   230  }
   231  
   232  // AddInterfaceAddr implements inet.Stack.AddInterfaceAddr.
   233  func (s *Stack) AddInterfaceAddr(idx int32, addr inet.InterfaceAddr) error {
   234  	protocolAddress, err := convertAddr(addr)
   235  	if err != nil {
   236  		return err
   237  	}
   238  
   239  	// Attach address to interface.
   240  	nicID := tcpip.NICID(idx)
   241  	if err := s.Stack.AddProtocolAddress(nicID, protocolAddress, stack.AddressProperties{}); err != nil {
   242  		return syserr.TranslateNetstackError(err).ToError()
   243  	}
   244  
   245  	// Add route for local network if it doesn't exist already.
   246  	localRoute := tcpip.Route{
   247  		Destination: protocolAddress.AddressWithPrefix.Subnet(),
   248  		Gateway:     tcpip.Address{}, // No gateway for local network.
   249  		NIC:         nicID,
   250  	}
   251  
   252  	for _, rt := range s.Stack.GetRouteTable() {
   253  		if rt.Equal(localRoute) {
   254  			return nil
   255  		}
   256  	}
   257  
   258  	// Local route does not exist yet. Add it.
   259  	s.Stack.AddRoute(localRoute)
   260  
   261  	return nil
   262  }
   263  
   264  // RemoveInterfaceAddr implements inet.Stack.RemoveInterfaceAddr.
   265  func (s *Stack) RemoveInterfaceAddr(idx int32, addr inet.InterfaceAddr) error {
   266  	protocolAddress, err := convertAddr(addr)
   267  	if err != nil {
   268  		return err
   269  	}
   270  
   271  	// Remove addresses matching the address and prefix.
   272  	nicID := tcpip.NICID(idx)
   273  	if err := s.Stack.RemoveAddress(nicID, protocolAddress.AddressWithPrefix.Address); err != nil {
   274  		return syserr.TranslateNetstackError(err).ToError()
   275  	}
   276  
   277  	// Remove the corresponding local network route if it exists.
   278  	localRoute := tcpip.Route{
   279  		Destination: protocolAddress.AddressWithPrefix.Subnet(),
   280  		Gateway:     tcpip.Address{}, // No gateway for local network.
   281  		NIC:         nicID,
   282  	}
   283  	s.Stack.RemoveRoutes(func(rt tcpip.Route) bool {
   284  		return rt.Equal(localRoute)
   285  	})
   286  
   287  	return nil
   288  }
   289  
   290  // TCPReceiveBufferSize implements inet.Stack.TCPReceiveBufferSize.
   291  func (s *Stack) TCPReceiveBufferSize() (inet.TCPBufferSize, error) {
   292  	var rs tcpip.TCPReceiveBufferSizeRangeOption
   293  	err := s.Stack.TransportProtocolOption(tcp.ProtocolNumber, &rs)
   294  	return inet.TCPBufferSize{
   295  		Min:     rs.Min,
   296  		Default: rs.Default,
   297  		Max:     rs.Max,
   298  	}, syserr.TranslateNetstackError(err).ToError()
   299  }
   300  
   301  // SetTCPReceiveBufferSize implements inet.Stack.SetTCPReceiveBufferSize.
   302  func (s *Stack) SetTCPReceiveBufferSize(size inet.TCPBufferSize) error {
   303  	rs := tcpip.TCPReceiveBufferSizeRangeOption{
   304  		Min:     size.Min,
   305  		Default: size.Default,
   306  		Max:     size.Max,
   307  	}
   308  	return syserr.TranslateNetstackError(s.Stack.SetTransportProtocolOption(tcp.ProtocolNumber, &rs)).ToError()
   309  }
   310  
   311  // TCPSendBufferSize implements inet.Stack.TCPSendBufferSize.
   312  func (s *Stack) TCPSendBufferSize() (inet.TCPBufferSize, error) {
   313  	var ss tcpip.TCPSendBufferSizeRangeOption
   314  	err := s.Stack.TransportProtocolOption(tcp.ProtocolNumber, &ss)
   315  	return inet.TCPBufferSize{
   316  		Min:     ss.Min,
   317  		Default: ss.Default,
   318  		Max:     ss.Max,
   319  	}, syserr.TranslateNetstackError(err).ToError()
   320  }
   321  
   322  // SetTCPSendBufferSize implements inet.Stack.SetTCPSendBufferSize.
   323  func (s *Stack) SetTCPSendBufferSize(size inet.TCPBufferSize) error {
   324  	ss := tcpip.TCPSendBufferSizeRangeOption{
   325  		Min:     size.Min,
   326  		Default: size.Default,
   327  		Max:     size.Max,
   328  	}
   329  	return syserr.TranslateNetstackError(s.Stack.SetTransportProtocolOption(tcp.ProtocolNumber, &ss)).ToError()
   330  }
   331  
   332  // TCPSACKEnabled implements inet.Stack.TCPSACKEnabled.
   333  func (s *Stack) TCPSACKEnabled() (bool, error) {
   334  	var sack tcpip.TCPSACKEnabled
   335  	err := s.Stack.TransportProtocolOption(tcp.ProtocolNumber, &sack)
   336  	return bool(sack), syserr.TranslateNetstackError(err).ToError()
   337  }
   338  
   339  // SetTCPSACKEnabled implements inet.Stack.SetTCPSACKEnabled.
   340  func (s *Stack) SetTCPSACKEnabled(enabled bool) error {
   341  	opt := tcpip.TCPSACKEnabled(enabled)
   342  	return syserr.TranslateNetstackError(s.Stack.SetTransportProtocolOption(tcp.ProtocolNumber, &opt)).ToError()
   343  }
   344  
   345  // TCPRecovery implements inet.Stack.TCPRecovery.
   346  func (s *Stack) TCPRecovery() (inet.TCPLossRecovery, error) {
   347  	var recovery tcpip.TCPRecovery
   348  	if err := s.Stack.TransportProtocolOption(tcp.ProtocolNumber, &recovery); err != nil {
   349  		return 0, syserr.TranslateNetstackError(err).ToError()
   350  	}
   351  	return inet.TCPLossRecovery(recovery), nil
   352  }
   353  
   354  // SetTCPRecovery implements inet.Stack.SetTCPRecovery.
   355  func (s *Stack) SetTCPRecovery(recovery inet.TCPLossRecovery) error {
   356  	opt := tcpip.TCPRecovery(recovery)
   357  	return syserr.TranslateNetstackError(s.Stack.SetTransportProtocolOption(tcp.ProtocolNumber, &opt)).ToError()
   358  }
   359  
   360  // Statistics implements inet.Stack.Statistics.
   361  func (s *Stack) Statistics(stat any, arg string) error {
   362  	switch stats := stat.(type) {
   363  	case *inet.StatDev:
   364  		for _, ni := range s.Stack.NICInfo() {
   365  			if ni.Name != arg {
   366  				continue
   367  			}
   368  			// TODO(gvisor.dev/issue/2103) Support stubbed stats.
   369  			*stats = inet.StatDev{
   370  				// Receive section.
   371  				ni.Stats.Rx.Bytes.Value(),   // bytes.
   372  				ni.Stats.Rx.Packets.Value(), // packets.
   373  				0,                           // errs.
   374  				0,                           // drop.
   375  				0,                           // fifo.
   376  				0,                           // frame.
   377  				0,                           // compressed.
   378  				0,                           // multicast.
   379  				// Transmit section.
   380  				ni.Stats.Tx.Bytes.Value(),   // bytes.
   381  				ni.Stats.Tx.Packets.Value(), // packets.
   382  				0,                           // errs.
   383  				0,                           // drop.
   384  				0,                           // fifo.
   385  				0,                           // colls.
   386  				0,                           // carrier.
   387  				0,                           // compressed.
   388  			}
   389  			break
   390  		}
   391  	case *inet.StatSNMPIP:
   392  		ip := Metrics.IP
   393  		// TODO(gvisor.dev/issue/969) Support stubbed stats.
   394  		*stats = inet.StatSNMPIP{
   395  			0,                          // Ip/Forwarding.
   396  			0,                          // Ip/DefaultTTL.
   397  			ip.PacketsReceived.Value(), // InReceives.
   398  			0,                          // Ip/InHdrErrors.
   399  			ip.InvalidDestinationAddressesReceived.Value(), // InAddrErrors.
   400  			0,                               // Ip/ForwDatagrams.
   401  			0,                               // Ip/InUnknownProtos.
   402  			0,                               // Ip/InDiscards.
   403  			ip.PacketsDelivered.Value(),     // InDelivers.
   404  			ip.PacketsSent.Value(),          // OutRequests.
   405  			ip.OutgoingPacketErrors.Value(), // OutDiscards.
   406  			0,                               // Ip/OutNoRoutes.
   407  			0,                               // Support Ip/ReasmTimeout.
   408  			0,                               // Support Ip/ReasmReqds.
   409  			0,                               // Support Ip/ReasmOKs.
   410  			0,                               // Support Ip/ReasmFails.
   411  			0,                               // Support Ip/FragOKs.
   412  			0,                               // Support Ip/FragFails.
   413  			0,                               // Support Ip/FragCreates.
   414  		}
   415  	case *inet.StatSNMPICMP:
   416  		in := Metrics.ICMP.V4.PacketsReceived.ICMPv4PacketStats
   417  		out := Metrics.ICMP.V4.PacketsSent.ICMPv4PacketStats
   418  		// TODO(gvisor.dev/issue/969) Support stubbed stats.
   419  		*stats = inet.StatSNMPICMP{
   420  			0, // Icmp/InMsgs.
   421  			Metrics.ICMP.V4.PacketsSent.Dropped.Value(), // InErrors.
   422  			0,                         // Icmp/InCsumErrors.
   423  			in.DstUnreachable.Value(), // InDestUnreachs.
   424  			in.TimeExceeded.Value(),   // InTimeExcds.
   425  			in.ParamProblem.Value(),   // InParmProbs.
   426  			in.SrcQuench.Value(),      // InSrcQuenchs.
   427  			in.Redirect.Value(),       // InRedirects.
   428  			in.EchoRequest.Value(),    // InEchos.
   429  			in.EchoReply.Value(),      // InEchoReps.
   430  			in.Timestamp.Value(),      // InTimestamps.
   431  			in.TimestampReply.Value(), // InTimestampReps.
   432  			in.InfoRequest.Value(),    // InAddrMasks.
   433  			in.InfoReply.Value(),      // InAddrMaskReps.
   434  			0,                         // Icmp/OutMsgs.
   435  			Metrics.ICMP.V4.PacketsReceived.Invalid.Value(), // OutErrors.
   436  			out.DstUnreachable.Value(),                      // OutDestUnreachs.
   437  			out.TimeExceeded.Value(),                        // OutTimeExcds.
   438  			out.ParamProblem.Value(),                        // OutParmProbs.
   439  			out.SrcQuench.Value(),                           // OutSrcQuenchs.
   440  			out.Redirect.Value(),                            // OutRedirects.
   441  			out.EchoRequest.Value(),                         // OutEchos.
   442  			out.EchoReply.Value(),                           // OutEchoReps.
   443  			out.Timestamp.Value(),                           // OutTimestamps.
   444  			out.TimestampReply.Value(),                      // OutTimestampReps.
   445  			out.InfoRequest.Value(),                         // OutAddrMasks.
   446  			out.InfoReply.Value(),                           // OutAddrMaskReps.
   447  		}
   448  	case *inet.StatSNMPTCP:
   449  		tcp := Metrics.TCP
   450  		// RFC 2012 (updates 1213):  SNMPv2-MIB-TCP.
   451  		*stats = inet.StatSNMPTCP{
   452  			1,                                     // RtoAlgorithm.
   453  			200,                                   // RtoMin.
   454  			120000,                                // RtoMax.
   455  			(1<<64 - 1),                           // MaxConn.
   456  			tcp.ActiveConnectionOpenings.Value(),  // ActiveOpens.
   457  			tcp.PassiveConnectionOpenings.Value(), // PassiveOpens.
   458  			tcp.FailedConnectionAttempts.Value(),  // AttemptFails.
   459  			tcp.EstablishedResets.Value(),         // EstabResets.
   460  			tcp.CurrentEstablished.Value(),        // CurrEstab.
   461  			tcp.ValidSegmentsReceived.Value(),     // InSegs.
   462  			tcp.SegmentsSent.Value(),              // OutSegs.
   463  			tcp.Retransmits.Value(),               // RetransSegs.
   464  			tcp.InvalidSegmentsReceived.Value(),   // InErrs.
   465  			tcp.ResetsSent.Value(),                // OutRsts.
   466  			tcp.ChecksumErrors.Value(),            // InCsumErrors.
   467  		}
   468  	case *inet.StatSNMPUDP:
   469  		udp := Metrics.UDP
   470  		// TODO(gvisor.dev/issue/969) Support stubbed stats.
   471  		*stats = inet.StatSNMPUDP{
   472  			udp.PacketsReceived.Value(),     // InDatagrams.
   473  			udp.UnknownPortErrors.Value(),   // NoPorts.
   474  			0,                               // Udp/InErrors.
   475  			udp.PacketsSent.Value(),         // OutDatagrams.
   476  			udp.ReceiveBufferErrors.Value(), // RcvbufErrors.
   477  			0,                               // Udp/SndbufErrors.
   478  			udp.ChecksumErrors.Value(),      // Udp/InCsumErrors.
   479  			0,                               // Udp/IgnoredMulti.
   480  		}
   481  	default:
   482  		return syserr.ErrEndpointOperation.ToError()
   483  	}
   484  	return nil
   485  }
   486  
   487  // RouteTable implements inet.Stack.RouteTable.
   488  func (s *Stack) RouteTable() []inet.Route {
   489  	var routeTable []inet.Route
   490  
   491  	for _, rt := range s.Stack.GetRouteTable() {
   492  		var family uint8
   493  		switch rt.Destination.ID().BitLen() {
   494  		case header.IPv4AddressSizeBits:
   495  			family = linux.AF_INET
   496  		case header.IPv6AddressSizeBits:
   497  			family = linux.AF_INET6
   498  		default:
   499  			log.Warningf("Unknown network protocol in route %+v", rt)
   500  			continue
   501  		}
   502  
   503  		dstAddr := rt.Destination.ID()
   504  		routeTable = append(routeTable, inet.Route{
   505  			Family: family,
   506  			DstLen: uint8(rt.Destination.Prefix()), // The CIDR prefix for the destination.
   507  
   508  			// Always return unspecified protocol since we have no notion of
   509  			// protocol for routes.
   510  			Protocol: linux.RTPROT_UNSPEC,
   511  			// Set statically to LINK scope for now.
   512  			//
   513  			// TODO(gvisor.dev/issue/595): Set scope for routes.
   514  			Scope: linux.RT_SCOPE_LINK,
   515  			Type:  linux.RTN_UNICAST,
   516  
   517  			DstAddr:         dstAddr.AsSlice(),
   518  			OutputInterface: int32(rt.NIC),
   519  			GatewayAddr:     rt.Gateway.AsSlice(),
   520  		})
   521  	}
   522  
   523  	return routeTable
   524  }
   525  
   526  // IPTables returns the stack's iptables.
   527  func (s *Stack) IPTables() (*stack.IPTables, error) {
   528  	return s.Stack.IPTables(), nil
   529  }
   530  
   531  // Pause implements inet.Stack.Pause.
   532  func (s *Stack) Pause() {
   533  	s.Stack.Pause()
   534  }
   535  
   536  // Restore implements inet.Stack.Restore.
   537  func (s *Stack) Restore() {
   538  	s.Stack.Restore()
   539  }
   540  
   541  // Resume implements inet.Stack.Resume.
   542  func (s *Stack) Resume() {
   543  	s.Stack.Resume()
   544  }
   545  
   546  // RegisteredEndpoints implements inet.Stack.RegisteredEndpoints.
   547  func (s *Stack) RegisteredEndpoints() []stack.TransportEndpoint {
   548  	return s.Stack.RegisteredEndpoints()
   549  }
   550  
   551  // CleanupEndpoints implements inet.Stack.CleanupEndpoints.
   552  func (s *Stack) CleanupEndpoints() []stack.TransportEndpoint {
   553  	return s.Stack.CleanupEndpoints()
   554  }
   555  
   556  // RestoreCleanupEndpoints implements inet.Stack.RestoreCleanupEndpoints.
   557  func (s *Stack) RestoreCleanupEndpoints(es []stack.TransportEndpoint) {
   558  	s.Stack.RestoreCleanupEndpoints(es)
   559  }
   560  
   561  // SetForwarding implements inet.Stack.SetForwarding.
   562  func (s *Stack) SetForwarding(protocol tcpip.NetworkProtocolNumber, enable bool) error {
   563  	if err := s.Stack.SetForwardingDefaultAndAllNICs(protocol, enable); err != nil {
   564  		return fmt.Errorf("SetForwardingDefaultAndAllNICs(%d, %t): %s", protocol, enable, err)
   565  	}
   566  	return nil
   567  }
   568  
   569  // PortRange implements inet.Stack.PortRange.
   570  func (s *Stack) PortRange() (uint16, uint16) {
   571  	return s.Stack.PortRange()
   572  }
   573  
   574  // SetPortRange implements inet.Stack.SetPortRange.
   575  func (s *Stack) SetPortRange(start uint16, end uint16) error {
   576  	return syserr.TranslateNetstackError(s.Stack.SetPortRange(start, end)).ToError()
   577  }