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