generator

package
v0.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package generator turns a configuration into a stream of packets.

Every traffic pattern implements the same small Generator interface, so the dataplane's transmit loop is identical whether it is sending UDP, TCP SYNs, an IMIX or a PCAP replay. Each queue gets its own Generator instance, owned by that queue's transmit goroutine alone, so nothing here locks and nothing allocates after construction.

Index

Constants

This section is empty.

Variables

View Source
var DefaultIMIX = []MixEntry{
	{Size: 64, Weight: 7},
	{Size: 594, Weight: 4},
	{Size: 1518, Weight: 1},
}

DefaultIMIX is the "simple IMIX", the conventional Internet mix used by almost every traffic generator: seven small frames, four medium, one large, in a 7:4:1 ratio.

The sizes are the classic ones — a 64-byte frame (40-byte IP packet, the size of a bare TCP ack), a 594-byte frame (576-byte IP packet, the old minimum reassembly buffer), and a 1518-byte frame (1500-byte IP packet, a full Ethernet MTU). The mean is 361.8 bytes of Ethernet frame, which is the familiar ~340-byte IMIX average measured at IP level plus the 18 bytes of Ethernet header and FCS wrapped around it.

The distribution is a plain table so another mix can be dropped in without touching the generator.

Functions

func Classify

func Classify(frame []byte) stats.Class

Classify reports the protocol bucket of a received frame. The receive loop uses it, and it is the same code path the PCAP generator uses on transmit so both directions count the same way.

func DescribeMix

func DescribeMix(mix []MixEntry) string

DescribeMix renders a mix for the review screen and the dashboard, e.g. "IMIX 7:4:1 (64/594/1518B), mean 362B".

func ExpandMix

func ExpandMix(mix []MixEntry) ([]int, error)

ExpandMix turns a weighted size distribution into the exact, repeating sequence of frame sizes a generator cycles through. The returned slice has one entry per unit of weight, so DefaultIMIX yields 12 sizes containing exactly seven 64s, four 594s and one 1518.

The order is smooth rather than grouped: instead of emitting all the small frames and then all the large ones, it interleaves them with a deterministic weighted round-robin (the same "smooth" scheduling nginx uses). That keeps the instantaneous bit rate close to the average rather than pulsing once per cycle, and it is fully reproducible.

func MeanSize

func MeanSize(mix []MixEntry) float64

MeanSize returns the average total frame size of a mix, in bytes.

func UsableAddresses

func UsableAddresses(p netip.Prefix) uint64

UsableAddresses reports how many destination addresses a prefix contributes, following the same network/broadcast rules as the per-family steppers. It is used to tell the user how many distinct destinations a CIDR really provides. An IPv6 prefix of /64 or shorter is reported as the max uint64.

Types

type Finite

type Finite interface {
	// Remaining returns how many packets are left, or -1 when unbounded.
	Remaining() int
}

Finite is implemented by generators that can run out of packets — currently only a one-pass PCAP replay. The transmit loop asks how many packets are still available so it never requests a batch it cannot fill, and stops when nothing is left.

type Flow

type Flow struct {
	SrcIP   netip.Addr
	DstIP   netip.Addr
	SrcPort uint16
	DstPort uint16
}

Flow is one flow's tuple. The other tuple components — IP protocol and VLAN ID — are fixed for a run and live in the packet template.

type FlowSpec

type FlowSpec struct {
	SrcIP netip.Addr   // fixed for every flow
	Dst   netip.Prefix // /32 for a single destination; wider to cycle
	// SrcPort is the first source port; flow n uses SrcPort+n.
	SrcPort uint16
	// DstPort is the destination port. It is fixed unless VaryDstPort is set,
	// because the usual test points many flows at one server port.
	DstPort     uint16
	VaryDstPort bool
	// Flows is how many distinct flows exist. Must be at least 1.
	Flows int
	// Scatter walks the flow space in a scrambled order instead of counting
	// through it. The set of flows is identical either way, and the order is
	// still completely deterministic — it just stops consecutive packets
	// carrying consecutive ports, which some receivers hash badly.
	Scatter bool
	// contains filtered or unexported fields
}

FlowSpec describes the deterministic flow space a run walks.

Flow n is a pure function of n: the same configuration always produces the same tuples in the same order, whatever the queue count, which is what makes a test reproducible and a capture comparable between runs.

func (FlowSpec) At

func (s FlowSpec) At(n int) Flow

At returns the tuple for flow n. n is taken modulo Flows, so callers may pass a freely incrementing counter.

type FrameSource

type FrameSource interface {
	// Len is how many frames the capture holds.
	Len() int
	// Frame returns the i-th frame's bytes and the gap since the frame before
	// it (zero for the first). The returned slice must not be modified.
	Frame(i int) (data []byte, gap time.Duration)
	// MaxLen and MeanLen are the largest and mean frame lengths in bytes.
	MaxLen() int
	MeanLen() int
	// Describe summarises the capture for the review screen.
	Describe() string
	// Warnings lists anything about the capture worth telling the user before
	// replaying it, such as packets truncated by the capture's snaplen.
	Warnings() []string
}

FrameSource supplies the frames of a loaded capture. It is an interface so the generator can be tested without touching a file, and so the PCAP reader stays in its own package.

type Generator

type Generator interface {
	// Next writes the next packet into frame and returns how many bytes it
	// wrote — the Ethernet frame length excluding the FCS the NIC appends —
	// along with the protocol class for statistics.
	Next(frame []byte) (int, stats.Class)

	// AvgWireBytes is the mean on-the-wire size of a packet, including the 20
	// bytes of preamble, start-frame delimiter and interframe gap. The rate
	// limiter charges this per packet up front and reconciles against the real
	// sizes afterwards, so it only has to be a good estimate.
	AvgWireBytes() int

	// MaxFrameLen is the largest frame this generator can emit, so the
	// dataplane can check it fits in a UMEM frame before attaching anything.
	MaxFrameLen() int

	// Describe is a short human-readable summary of the packet-size behaviour,
	// e.g. "fixed 64-byte frames" or "IMIX 7:4:1 (64/594/1518B)".
	Describe() string
}

Generator produces the packets one queue transmits.

A Generator is owned by exactly one transmit goroutine. Implementations must not allocate in Next: the whole point is that a 10 Gbit/s run does no per-packet memory work.

func New

func New(s Spec) (Generator, error)

New builds the generator for one queue.

type MixEntry

type MixEntry struct {
	// Size is the total Ethernet frame size in bytes, including the 4-byte
	// FCS — the same units as --packet-size.
	Size int
	// Weight is how many packets of this size appear per cycle.
	Weight int
}

MixEntry is one frame size in a size distribution and how often it occurs relative to the others.

type Pacer

type Pacer interface {
	// Delay is how long to wait before producing the next packet.
	Delay() time.Duration
}

Pacer is implemented by generators that carry their own timing, currently only PCAP replay preserving a capture's original inter-packet gaps. When a Generator also implements Pacer the transmit loop sends one packet at a time and waits the returned delay in between, obeying whichever of the pacer and the rate limiter is slower.

type Spec

type Spec struct {
	Cfg    *config.Config
	SrcMAC [6]byte
	DstMAC [6]byte
	SrcIP  netip.Addr
	Dst    netip.Prefix

	// Queue and Queues place this generator in the flow space.
	Queue, Queues int

	// Frames is the PCAP replay source, required for config.ModePCAP.
	Frames FrameSource
}

Spec is everything the factory needs to build a queue's generator. The addressing is already resolved: discovery has picked the source address and the next-hop MAC before this point.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL