github.com/jspc/eggos@v0.5.1-0.20221028160421-556c75c878a5/inet/endpoint.go (about)

     1  package inet
     2  
     3  import (
     4  	"sync"
     5  
     6  	"gvisor.dev/gvisor/pkg/tcpip"
     7  	"gvisor.dev/gvisor/pkg/tcpip/buffer"
     8  	"gvisor.dev/gvisor/pkg/tcpip/header"
     9  	"gvisor.dev/gvisor/pkg/tcpip/link/ethernet"
    10  	"gvisor.dev/gvisor/pkg/tcpip/stack"
    11  )
    12  
    13  type endpoint struct {
    14  	eth        *ethernet.Endpoint
    15  	cap        stack.LinkEndpointCapabilities
    16  	addr       tcpip.LinkAddress
    17  	dispatcher stack.NetworkDispatcher
    18  
    19  	// protect the following fields.
    20  	mutex  sync.Mutex
    21  	device Device
    22  }
    23  
    24  type Options struct {
    25  	// MTU is the mtu to use for this endpoint.
    26  	MTU uint32
    27  
    28  	// Address is the link address for this endpoint. Only used if
    29  	// EthernetHeader is true.
    30  	Address tcpip.LinkAddress
    31  }
    32  
    33  func New(opt *Options) stack.LinkEndpoint {
    34  	mac := DefaultDevice.Mac()
    35  	e := &endpoint{
    36  		addr:   tcpip.LinkAddress(mac[:]),
    37  		device: DefaultDevice,
    38  	}
    39  	e.eth = ethernet.New(e)
    40  
    41  	e.device.SetReceiveCallback(e.onrx)
    42  	return e.eth
    43  }
    44  
    45  // MTU is the maximum transmission unit for this endpoint. This is
    46  // usually dictated by the backing physical network; when such a
    47  // physical network doesn't exist, the limit is generally 64k, which
    48  // includes the maximum size of an IP packet.
    49  func (e *endpoint) MTU() uint32 {
    50  	return 1500
    51  }
    52  
    53  // Capabilities returns the set of capabilities supported by the
    54  // endpoint.
    55  func (e *endpoint) Capabilities() stack.LinkEndpointCapabilities {
    56  	return e.cap
    57  }
    58  
    59  // MaxHeaderLength returns the maximum size the data link (and
    60  // lower level layers combined) headers can have. Higher levels use this
    61  // information to reserve space in the front of the packets they're
    62  // building.
    63  func (e *endpoint) MaxHeaderLength() uint16 {
    64  	return 0
    65  }
    66  
    67  // LinkAddress returns the link address (typically a MAC) of the
    68  // link endpoint.
    69  func (e *endpoint) LinkAddress() tcpip.LinkAddress {
    70  	return e.addr
    71  }
    72  
    73  // AddHeader adds a link layer header to pkt if required.
    74  func (e *endpoint) AddHeader(local tcpip.LinkAddress, remote tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) {
    75  	panic("not implemented") // TODO: Implement
    76  }
    77  
    78  // WritePacket writes a packet with the given protocol through the
    79  // given route. It sets pkt.LinkHeader if a link layer header exists.
    80  // pkt.NetworkHeader and pkt.TransportHeader must have already been
    81  // set.
    82  //
    83  // To participate in transparent bridging, a LinkEndpoint implementation
    84  // should call eth.Encode with header.EthernetFields.SrcAddr set to
    85  // r.LocalLinkAddress if it is provided.
    86  
    87  func (e *endpoint) WritePacket(r stack.RouteInfo, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) tcpip.Error {
    88  	e.mutex.Lock()
    89  	err := e.device.Transmit(pkt)
    90  	if err != nil {
    91  		e.mutex.Unlock()
    92  		return new(tcpip.ErrAlreadyBound)
    93  	}
    94  	e.mutex.Unlock()
    95  	return nil
    96  }
    97  
    98  // WritePackets writes packets with the given protocol through the
    99  // given route.
   100  //
   101  // Right now, WritePackets is used only when the software segmentation
   102  // offload is enabled. If it will be used for something else, it may
   103  // require to change syscall filters.
   104  func (e *endpoint) WritePackets(stack.RouteInfo, stack.PacketBufferList, tcpip.NetworkProtocolNumber) (int, tcpip.Error) {
   105  	panic("not implemented") // TODO: Implement
   106  }
   107  
   108  // WriteRawPacket writes a packet directly to the link. The packet
   109  // should already have an ethernet header.
   110  func (e *endpoint) WriteRawPacket(vv buffer.VectorisedView) *tcpip.Error {
   111  	panic("not implemented") // TODO: Implement
   112  }
   113  
   114  // Attach attaches the data link layer endpoint to the network-layer
   115  // dispatcher of the stack.
   116  func (e *endpoint) Attach(dispatcher stack.NetworkDispatcher) {
   117  	e.dispatcher = dispatcher
   118  }
   119  
   120  // IsAttached returns whether a NetworkDispatcher is attached to the
   121  // endpoint.
   122  func (e *endpoint) IsAttached() bool {
   123  	return e.dispatcher != nil
   124  }
   125  
   126  func (e *endpoint) ARPHardwareType() header.ARPHardwareType {
   127  	return header.ARPHardwareEther
   128  }
   129  
   130  // Wait waits for any worker goroutines owned by the endpoint to stop.
   131  //
   132  // For now, requesting that an endpoint's worker goroutine(s) stop is
   133  // implementation specific.
   134  //
   135  // Wait will not block if the endpoint hasn't started any goroutines
   136  // yet, even if it might later.
   137  func (e *endpoint) Wait() {
   138  }
   139  
   140  func (e *endpoint) onrx(buf []byte) {
   141  	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{})
   142  	pkt.Data().AppendView(buffer.NewViewFromBytes(buf))
   143  	e.eth.DeliverNetworkPacket(tcpip.LinkAddress(""), tcpip.LinkAddress(""), 0, pkt)
   144  }