Files
netstack/tcpip/stack/route.go

114 lines
3.1 KiB
Go

package stack
import (
"netstack/sleep"
"netstack/tcpip"
"netstack/tcpip/buffer"
)
// 贯穿整个协议栈的路由,也就是在链路层和网络层都可以路由
// 如果目标地址是链路层地址,那么在链路层路由,
// 如果目标地址是网络层地址,那么在网络层路由。
type Route struct {
// 远端网络层地址 ipv4 or ipv6 地址
RemoteAddress tcpip.Address
// 远端网卡MAC地址
RemoteLinkAddress tcpip.LinkAddress
// 本地网络层地址 ipv4 or ipv6 地址
LocalAddress tcpip.Address
// 本地网卡MAC地址
LocalLinkAddress tcpip.LinkAddress
// 下一跳网络层地址
NextHop tcpip.Address
// 网络层协议号
NetProto tcpip.NetworkProtocolNumber
// 相关的网络终端
ref *referencedNetworkEndpoint
}
// 根据参数新建一个路由,并关联一个网络层端
func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address,
localLinkAddr tcpip.LinkAddress, ref *referencedNetworkEndpoint) Route {
return Route{
NetProto: netProto,
LocalAddress: localAddr,
LocalLinkAddress: localLinkAddr,
RemoteAddress: remoteAddr,
ref: ref,
}
}
// NICID returns the id of the NIC from which this route originates.
func (r *Route) NICID() tcpip.NICID {
return r.ref.ep.NICID()
}
// MaxHeaderLength forwards the call to the network endpoint's implementation.
func (r *Route) MaxHeaderLength() uint16 {
return r.ref.ep.MaxHeaderLength()
}
// Stats returns a mutable copy of current stats.
func (r *Route) Stats() tcpip.Stats {
return r.ref.nic.stack.Stats()
}
// Capabilities returns the link-layer capabilities of the route.
func (r *Route) Capabilities() LinkEndpointCapabilities {
return r.ref.ep.Capabilities()
}
// RemoveWaker removes a waker that has been added in Resolve().
func (r *Route) RemoveWaker(waker *sleep.Waker) {
nextAddr := r.NextHop
if nextAddr == "" {
nextAddr = r.RemoteAddress
}
r.ref.linkCache.RemoveWaker(r.ref.nic.ID(), nextAddr, waker)
}
// IsResolutionRequired returns true if Resolve() must be called to resolve
// the link address before the this route can be written to.
func (r *Route) IsResolutionRequired() bool {
return r.ref.linkCache != nil && r.RemoteLinkAddress == ""
}
// WritePacket writes the packet through the given route.
func (r *Route) WritePacket(hdr buffer.Prependable, payload buffer.VectorisedView,
protocol tcpip.TransportProtocolNumber, ttl uint8) *tcpip.Error {
err := r.ref.ep.WritePacket(r, hdr, payload, protocol, ttl)
if err == tcpip.ErrNoRoute {
r.Stats().IP.OutgoingPacketErrors.Increment()
}
return err
}
// DefaultTTL returns the default TTL of the underlying network endpoint.
func (r *Route) DefaultTTL() uint8 {
return r.ref.ep.DefaultTTL()
}
// MTU returns the MTU of the underlying network endpoint.
func (r *Route) MTU() uint32 {
return r.ref.ep.MTU()
}
// Release frees all resources associated with the route.
func (r *Route) Release() {
if r.ref != nil {
r.ref.decRef()
r.ref = nil
}
}
// Clone Clone a route such that the original one can be released and the new
// one will remain valid.
func (r *Route) Clone() Route {
r.ref.incRef()
return *r
}