Files
netstack/tcpip/stack/registration.go
2022-11-24 19:35:26 +08:00

169 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package stack
import (
"netstack/ilist"
"netstack/sleep"
"netstack/tcpip"
"netstack/tcpip/buffer"
"sync"
)
const (
CapabilityChecksumOffload LinkEndpointCapabilities = 1 << iota
CapabilityResolutionRequired
CapabilitySaveRestore
CapabilityDisconnectOK
CapabilityLoopback
)
// ====================链路层相关==============================
// 所谓 io 就是数据的输入输出,对于网卡来说就是接收或发送数据,
// 接收意味着对以太网帧解封装和提交给网络层,发送意味着对上层数据的封装和写入网卡
// 链路层接口
type LinkEndpoint interface {
// MTU是此端点的最大传输单位。这通常由支持物理网络决定;
// 当这种物理网络不存在时限制通常为64k其中包括IP数据包的最大大小。
MTU() uint32
// Capabilities返回链路层端点支持的功能集。
Capabilities() LinkEndpointCapabilities
// MaxHeaderLength 返回数据链接(和较低级别的图层组合)标头可以具有的最大大小。
// 较高级别使用此信息来保留它们正在构建的数据包前面预留空间。
MaxHeaderLength() uint16
// 本地链路层地址
LinkAddress() tcpip.LinkAddress
// 要参与透明桥接LinkEndpoint实现应调用eth.Encode
// 并将header.EthernetFields.SrcAddr设置为r.LocalLinkAddress如果已提供
WritePacket(r *Route, hdr buffer.Prependable, payload buffer.VectorisedView,
protocol tcpip.NetworkProtocolNumber) *tcpip.Error
// Attach 将数据链路层端点附加到协议栈的网络层调度程序。
Attach(dispatcher NetworkDispatcher)
// 是否已经添加了网络层调度器
IsAttached() bool
}
// LinkAddressResolver 是对可以解析链接地址的 NetworkProtocol 的扩展 TODO 需要解读
type LinkAddressResolver interface {
LinkAddressRequest(addr, localAddr tcpip.Address, linkEP LinkEndpoint) *tcpip.Error
ResolveStaticAddress(addr tcpip.Address) (tcpip.LinkAddress, bool)
LinkAddressProtocol() tcpip.NetworkProtocolNumber
}
// A LinkAddressCache caches link addresses.
type LinkAddressCache interface {
// CheckLocalAddress determines if the given local address exists, and if it
// does not exist.
CheckLocalAddress(nicid tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) tcpip.NICID
// AddLinkAddress adds a link address to the cache.
AddLinkAddress(nicid tcpip.NICID, addr tcpip.Address, linkAddr tcpip.LinkAddress)
// GetLinkAddress looks up the cache to translate address to link address (e.g. IP -> MAC).
// If the LinkEndpoint requests address resolution and there is a LinkAddressResolver
// registered with the network protocol, the cache attempts to resolve the address
// and returns ErrWouldBlock. Waker is notified when address resolution is
// complete (success or not).
//
// If address resolution is required, ErrNoLinkAddress and a notification channel is
// returned for the top level caller to block. Channel is closed once address resolution
// is complete (success or not).
GetLinkAddress(nicid tcpip.NICID, addr, localAddr tcpip.Address, protocol tcpip.NetworkProtocolNumber, w *sleep.Waker) (tcpip.LinkAddress, <-chan struct{}, *tcpip.Error)
// RemoveWaker removes a waker that has been added in GetLinkAddress().
RemoveWaker(nicid tcpip.NICID, addr tcpip.Address, waker *sleep.Waker)
}
type NetworkDispatcher interface {
DeliverNetworkPacket(linkEP LinkEndpoint, dstLinkAddr, srcLinkAddr tcpip.LinkAddress,
protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView)
}
type LinkEndpointCapabilities uint
var (
// 传输层协议的注册存储结构 TODO
// 网络层协议的注册存储结构 TODO
linkEPMu sync.RWMutex
nextLinkEndpointID tcpip.LinkEndpointID = 1
linkEndpoints = make(map[tcpip.LinkEndpointID]LinkEndpoint) // 设备注册表 设备号:设备实现
)
// ==============================网络层相关==============================
type NetworkProtocol interface {
// TODO 需要添加
}
// NetworkEndpoint是需要由网络层协议例如ipv4ipv6的端点实现的接口
type NetworkEndpoint interface {
// TODO 需要添加
}
type NetworkEndpoingID struct {
LocalAddress tcpip.Address
}
// ==============================传输层相关==============================
type TransportEndpointID struct {
// TODO
}
// ControlType 是网络层控制消息的类型
type ControlType int
// TODO 需要解读
type TransportEndpoint interface {
HandlePacket(r *Route, id TransportEndpointID, vv buffer.VectorisedView)
HandleControlPacker(id TransportEndpointID, typ ControlType, extra uint32, vv buffer.VectorisedView)
}
// TODO 需要解读
type referencedNetworkEndpoint struct {
ilist.Entry
refs int32
ep NetworkEndpoint
nic *NIC
protocol tcpip.NetworkProtocolNumber
// linkCache is set if link address resolution is enabled for this
// protocol. Set to nil otherwise.
linkCache LinkAddressCache
linkAddrCache
// holdsInsertRef is protected by the NIC's mutex. It indicates whether
// the reference count is biased by 1 due to the insertion of the
// endpoint. It is reset to false when RemoveAddress is called on the
// NIC.
holdsInsertRef bool
}
// 注册一个链路层设备
func RegisterLinkEndpoint(linkEP LinkEndpoint) tcpip.LinkEndpointID {
linkEPMu.Lock()
defer linkEPMu.Unlock()
v := nextLinkEndpointID
nextLinkEndpointID++
linkEndpoints[v] = linkEP
return v
}
func FindLinkEndpoint(id tcpip.LinkEndpointID) LinkEndpoint {
linkEPMu.RLock()
defer linkEPMu.RUnlock()
return linkEndpoints[id]
}