Documentation
¶
Index ¶
- Constants
- Variables
- func ClassOfSize(pktSize int) sizeClass
- func ResolveAddrPort(s string) (netip.AddrPort, error)
- func UpdateOutputMetrics(ctx context.Context, metrics *InterfaceMetrics, packets []*Packet)
- type DataPlane
- type InterfaceMetrics
- type Link
- type LinkScope
- type Metrics
- type Packet
- type PacketPool
- type RunConfig
- type Services
- type Session
- type Type
- type UDPProvider
- func (u *UDPProvider) AddSvc(svc addr.SVC, host addr.Host, port uint16) error
- func (u *UDPProvider) DelSvc(svc addr.SVC, host addr.Host, port uint16) error
- func (u *UDPProvider) Headroom() int
- func (u *UDPProvider) NewExternalLink(qSize int, bfd Session, local string, remote string, ifID uint16, ...) (Link, error)
- func (u *UDPProvider) NewInternalLink(local string, qSize int, metrics *InterfaceMetrics) (Link, error)
- func (u *UDPProvider) NumConnections() int
- func (u *UDPProvider) Start(ctx context.Context, pool PacketPool, procQs []chan *Packet)
- func (u *UDPProvider) Stop()
- type UnderlayProvider
Constants ¶
const ( UDPIPv4Name = "UDP/IPv4" UDPIPv6Name = "UDP/IPv6" UDPIPv46Name = "UDP/IPv4+6" )
const ( // TODO(karampok). Investigate whether that value should be higher. In // theory, PayloadLen in SCION header is 16 bits long, supporting a maximum // payload size of 64KB. At the moment we are limited by Ethernet size // usually ~1500B, but 9000B to support jumbo frames. // TODO(multi_underlay): The buffer size should be a function of the collection of // underlays (the largest frame size of all the enabled ones). BufferSize = 9000 )
const ( // EndhostPort is the underlay port that SCION binds to on non-routers. Subject to // change during standardisation. EndhostPort = 30041 )
Variables ¶
Functions ¶
func ClassOfSize ¶
func ClassOfSize(pktSize int) sizeClass
func ResolveAddrPort ¶
ResolveAddrPort resolves a "host:port" address. IPv4 addresses in the v4-mapped IPv6 form are normalized to plain IPv4.
func UpdateOutputMetrics ¶
func UpdateOutputMetrics(ctx context.Context, metrics *InterfaceMetrics, packets []*Packet)
UpdateOutputMetrics accounts for the given packets in the output metrics, aggregated by traffic type and size class.
Types ¶
type DataPlane ¶
type DataPlane struct {
RunConfig RunConfig
// contains filtered or unexported fields
}
func NewDataPlane ¶
func NewDataPlane( ia addr.IA, host addr.Host, key []byte, provider UnderlayProvider, links []Link, ) (*DataPlane, error)
NewDataPlane creates a data plane for the given IA. The links must include at most one link with IfID 0 (the internal link) and are indexed by their interface ID. All links must have been created by the given provider.
type InterfaceMetrics ¶
type InterfaceMetrics [maxSizeClass]trafficMetrics
interfaceMetrics is the set of metrics that are relevant for one given interface. It is a map that associates each (traffic-type, size-class) pair with the set of metrics belonging to that interface that have these label values. This set of metrics is itself a trafficMetric structure. Explanation: Metrics are labeled by interface, local-as, neighbor-as, packet size, and (for output metrics only) traffic type. Instances are grouped in a hierarchical manner for efficient access by the using code. forwardingMetrics is a map of interface to interfaceMetrics. To access a specific InputPacketsTotal counter, one refers to:
dataplane.forwardingMetrics[interface][size-class].
trafficMetrics.Output is an array of outputMetrics indexed by traffic type.
type Link ¶
type Link interface {
// IsUp returns whether this link is functional according to the associated BFD session.
IsUp() bool
// IfID returns the interface ID associated with this link. 0 for sibling and internal links.
IfID() uint16
// Metrics returns the metrics specific to this link.
Metrics() *InterfaceMetrics
// Scope returns the scope of this link: internal, external, or sibling.
Scope() LinkScope
// BFDSession returns the BFD session associated with this link.
BFDSession() Session
// Resolve finds and sets the packet's internal underlay destination for the given dst and port.
Resolve(p *Packet, dst addr.Host, port uint16) error
// Send queues the packet for sending over this link; discarding if the queue is full.
Send(p *Packet) bool
// SendBlocking queues the packet for sending over this link; blocking while the queue is full.
SendBlocking(p *Packet)
}
Link embodies the router's idea of a point to point connection. A link associates the underlay connection with a BFDSession, a destination address, etc. It also allows the concrete send operation to be delegated to different underlay implementations. The association between link and underlay connection is a channel, on the sending side, and a demultiplexer on the receiving side. The demultiplexer must have a src-addr:link map in all cases where links share connections.
Regardless of underlay, links come in three scopes: internal, sibling, and external. The difference in behaviour is hidden from the rest of the router. The router only needs to associate an interface ID with a link. If the interface ID belongs to a sibling router, then the link is a sibling link. If the interface ID is zero, then the link is the internal link.
Note about Resolve. It resolves the given SCION host/svc address to an address on this underlay. This functionality is really only needed on the internal link,
type LinkScope ¶
type LinkScope int
LinkScope describes the kind (or scope) of a link: internal, sibling, or external.
type Metrics ¶
type Metrics struct {
// contains filtered or unexported fields
}
Metrics holds the metric instruments shared by all interfaces of a data plane. The instruments are created from the global otel meter provider; if none is configured, all counters are no-ops.
func NewMetrics ¶
func (*Metrics) NewInterfaceMetrics ¶
func (m *Metrics) NewInterfaceMetrics(ifID uint16, localIA, neighbor addr.IA) *InterfaceMetrics
NewInterfaceMetrics returns the metrics for one interface, labeled by the given interface ID, local IA, and neighbor IA.
type Packet ¶
type Packet struct {
// The useful part of the raw packet at a point in time (i.e. a slice of the full buffer). It
// can be any portion of the full buffer; not necessarily the start. This code maintains the
// invariant that RawPacket always represents the portion of a packet that immediately follows
// any underlay provider header. See also dataplane.underlayHeadroom.
RawPacket []byte
// The source address during ingest and the destination during forwarding. We never need both
// src and dst at the same time. The real type is only known to underlay provider that sets it.
RemoteAddr unsafe.Pointer
// The ingest link; which can give us the ifID, scope, bfdSession...
Link Link
// contains filtered or unexported fields
}
Packet aggregates buffers and ancillary metadata related to one packet. That is everything we need to pass-around while processing a packet. The motivation is to save on copy (pass everything via one reference) AND garbage collection (reuse everything). The buffer is allocated in a separate location (but still reused) to keep the packet structures tightly packed (might not matter, though). Golang gives precious little guarantees about alignment and padding. We do it ourselves in such a way that Go has no sane reason to add any padding. Everything is 8 byte aligned (on 64 bit arch) until SlowpathRequest which is 4 bytes long. The rest is in decreasing order of size and size-aligned. We want to fit neatly into cache lines, so we need to fit in 64 bytes. The padding required to occupy exactly 64 bytes depends on the architecture.
func (*Packet) WithHeader ¶
WithHeader returns the a slice of the underlying packet buffer that represents the same bytes as p.rawPacket[:] plus the n prededing bytes. This slice is meant to be used when receiving a raw packet with an n bytes header, such that the payload is exactly at p.rawPacket[0:]. p.RawPacket is *not* modified. This method panics if n is greater than the available headroom in the packet buffer.
type PacketPool ¶
type PacketPool struct {
// contains filtered or unexported fields
}
PacketPool allocates and resets packets. There is one packet pool per instance of the dataplane, shared between all its underlay instances. This structure can be shared by copying (and doing so is more efficient) because headroom is never changed after construction and channel is a reference type.
func (*PacketPool) Get ¶
func (p *PacketPool) Get() *Packet
Get fetches a packet from the pool and returns it initialized with the proper headroom. That is, pkt.rawPacket[0:] is where the packet's payload must go. Underlay providers may use any part of that, and MUST update the pkt.rawPacket slice to indicate where the packet's payload starts. However they may only use the preceding portion of the packet buffer to store a link-layer header. See also WithHeader
func (*PacketPool) Put ¶
func (p *PacketPool) Put(pkt *Packet)
Put returns the given packet to the pool.
type Services ¶
type Services[addrT comparable] struct { // contains filtered or unexported fields }
Services is a generic anycast address map, for use by underlay providers to implement the SCION service mapping.
func NewServices ¶
func NewServices[addrT comparable]() *Services[addrT]
type Type ¶
type Type int
func TypeFromString ¶
func (Type) MarshalJSON ¶
func (*Type) UnmarshalJSON ¶
type UDPProvider ¶
type UDPProvider struct {
// contains filtered or unexported fields
}
UDPProvider implements UnderlayProvider over UDP/IP. External links get an exclusive connected socket; the internal link uses a single unconnected socket.
func NewUDPProvider ¶
func NewUDPProvider(batchSize int, receiveBufferSize int, sendBufferSize int) *UDPProvider
NewUDPProvider returns a new provider for exclusive use by the caller.
func (*UDPProvider) Headroom ¶
func (u *UDPProvider) Headroom() int
func (*UDPProvider) NewExternalLink ¶
func (u *UDPProvider) NewExternalLink( qSize int, bfd Session, local string, remote string, ifID uint16, metrics *InterfaceMetrics, ) (Link, error)
NewExternalLink returns an external link over the UDP/IP underlay, always implemented with a connectedLink.
func (*UDPProvider) NewInternalLink ¶
func (u *UDPProvider) NewInternalLink( local string, qSize int, metrics *InterfaceMetrics, ) (Link, error)
NewInternalLink returns an internal link over the UDP/IP underlay. At most one internal link is supported.
func (*UDPProvider) NumConnections ¶
func (u *UDPProvider) NumConnections() int
func (*UDPProvider) Start ¶
func (u *UDPProvider) Start( ctx context.Context, pool PacketPool, procQs []chan *Packet, )
Start puts the provider in the running state. The queues to be used by the receiver tasks are supplied at this point because they must be sized according to the number of connections that will be started.
func (*UDPProvider) Stop ¶
func (u *UDPProvider) Stop()
type UnderlayProvider ¶
type UnderlayProvider interface {
// NumConnections returns the current number of configured connections.
NumConnections() int
// Headroom returns the length of the largest header possibly added by this underlay.
// The dataplane ensures that all received packets are stored at an offset in the packet
// buffer such that the largest underlay header declared across all underlay providers can
// be prepended to the SCION header without having to copy the packet or to allocate a
// separate buffer.
Headroom() int
// NewExternalLink returns a link that addresses a single remote AS at a unique underlay
// address. Outgoing packets do not need an underlay destination as metadata. Incoming
// packets have a defined ingress ifID.
NewExternalLink(
qSize int,
bfd Session,
local string,
remote string,
ifID uint16,
metrics *InterfaceMetrics,
) (Link, error)
// NewInternalLink returns a link that addresses any host internal to the enclosing AS.
// Outgoing packets need to have a destination address as metadata. Incoming packets have
// no defined ingress ifID.
NewInternalLink(localAddr string, qSize int, metrics *InterfaceMetrics) (Link, error)
// Start puts the provider in the running state. In that state, the provider delivers
// incoming packets to the given processor queues and sends the packets queued on its
// links. Only connections in existence at the time of calling Start are started.
Start(ctx context.Context, pool PacketPool, procQs []chan *Packet)
// Stop puts the provider in the stopped state. In that state, the provider no longer
// delivers incoming packets and ignores packets present on its input channels.
Stop()
}
UnderlayProvider is a provider of connectivity over some underlay implementation. It owns the connections that carry the traffic of the links it creates.