multicast

package
v0.0.0-...-1a9f8b1 Latest Latest
Warning

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

Go to latest
Published: Dec 23, 2024 License: Apache-2.0, MIT Imports: 6 Imported by: 0

Documentation

Overview

Package multicast contains utilities for supporting multicast routing.

Example

Example shows how to interact with a multicast RouteTable.

package main

import (
	"fmt"
	"time"

	"gvisor.dev/gvisor/pkg/buffer"
	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/faketime"
	"gvisor.dev/gvisor/pkg/tcpip/network/internal/multicast"
	"gvisor.dev/gvisor/pkg/tcpip/stack"
	"gvisor.dev/gvisor/pkg/tcpip/testutil"
)

const (
	defaultMinTTL = 10

	inputNICID    tcpip.NICID = 1
	outgoingNICID tcpip.NICID = 2
)

func main() {
	address := testutil.MustParse4("192.168.1.1")
	defaultOutgoingInterfaces := []stack.MulticastRouteOutgoingInterface{{ID: outgoingNICID, MinTTL: defaultMinTTL}}
	routeKey := stack.UnicastSourceAndMulticastDestination{Source: address, Destination: address}
	multicastRoute := stack.MulticastRoute{inputNICID, defaultOutgoingInterfaces}

	pkt := newPacketBuffer("hello")
	defer pkt.DecRef()

	clock := faketime.NewManualClock()
	clock.Advance(10 * time.Second)

	// Create a route table from a specified config.
	table := multicast.RouteTable{}
	defer table.Close()
	config := multicast.DefaultConfig(clock)

	if err := table.Init(config); err != nil {
		panic(err)
	}

	// Each entry in the table represents either an installed route or a pending
	// route. To insert a pending route, call:
	result, hasBufferSpace := table.GetRouteOrInsertPending(routeKey, pkt)

	// Callers should handle a no buffer space error (e.g. only deliver the
	// packet locally).
	if !hasBufferSpace {
		deliverPktLocally(pkt)
	}

	// Callers should handle the various pending route states.
	switch result.GetRouteResultState {
	case multicast.InstalledRouteFound:
		// The packet can be forwarded using the installed route.
		forwardPkt(pkt, result.InstalledRoute)
	case multicast.NoRouteFoundAndPendingInserted:
		// The route has just entered the pending state.
		emitMissingRouteEvent(routeKey)
		deliverPktLocally(pkt)
	case multicast.PacketQueuedInPendingRoute:
		// The route was already in the pending state.
		deliverPktLocally(pkt)
	}

	// To transition a pending route to the installed state, call:
	route := table.NewInstalledRoute(multicastRoute)
	pendingPackets := table.AddInstalledRoute(routeKey, route)

	// If there was a pending route, then the caller is responsible for
	// flushing any pending packets.
	for _, pkt := range pendingPackets {
		forwardPkt(pkt, route)
		pkt.DecRef()
	}

	// To obtain the last used time of the route, call:
	timestamp, found := table.GetLastUsedTimestamp(routeKey)

	if !found {
		panic(fmt.Sprintf("table.GetLastUsedTimestamp(%#v) = (_, false)", routeKey))
	}

	fmt.Printf("Last used timestamp: %s", timestamp)

	// Finally, to remove an installed route, call:
	if removed := table.RemoveInstalledRoute(routeKey); !removed {
		panic(fmt.Sprintf("table.RemoveInstalledRoute(%#v) = false", routeKey))
	}

}

func forwardPkt(*stack.PacketBuffer, *multicast.InstalledRoute) {
	fmt.Println("forwardPkt")
}

func emitMissingRouteEvent(stack.UnicastSourceAndMulticastDestination) {
	fmt.Println("emitMissingRouteEvent")
}

func deliverPktLocally(*stack.PacketBuffer) {
	fmt.Println("deliverPktLocally")
}

func newPacketBuffer(body string) *stack.PacketBuffer {
	return stack.NewPacketBuffer(stack.PacketBufferOptions{
		Payload: buffer.MakeWithData([]byte(body)),
	})
}
Output:

emitMissingRouteEvent
deliverPktLocally
forwardPkt
Last used timestamp: 10000000000

Index

Examples

Constants

View Source
const (
	// DefaultMaxPendingQueueSize corresponds to the number of elements that can
	// be in the packet queue for a pending route.
	//
	// Matches the Linux default queue size:
	// https://github.com/torvalds/linux/blob/26291c54e11/net/ipv6/ip6mr.c#L1186
	DefaultMaxPendingQueueSize uint8 = 3

	// DefaultPendingRouteExpiration is the default maximum lifetime of a pending
	// route.
	//
	// Matches the Linux default:
	// https://github.com/torvalds/linux/blob/26291c54e11/net/ipv6/ip6mr.c#L991
	DefaultPendingRouteExpiration time.Duration = 10 * time.Second

	// DefaultCleanupInterval is the default frequency of the routine that
	// expires pending routes.
	//
	// Matches the Linux default:
	// https://github.com/torvalds/linux/blob/26291c54e11/net/ipv6/ip6mr.c#L793
	DefaultCleanupInterval time.Duration = 10 * time.Second
)

Variables

View Source
var (
	// ErrNoBufferSpace indicates that no buffer space is available in the
	// pending route packet queue.
	ErrNoBufferSpace = errors.New("unable to queue packet, no buffer space available")

	// ErrMissingClock indicates that a clock was not provided as part of the
	// Config, but is required.
	ErrMissingClock = errors.New("clock must not be nil")

	// ErrAlreadyInitialized indicates that RouteTable.Init was already invoked.
	ErrAlreadyInitialized = errors.New("table is already initialized")
)

Functions

This section is empty.

Types

type Config

type Config struct {
	// MaxPendingQueueSize corresponds to the maximum number of queued packets
	// for a pending route.
	//
	// If the caller attempts to queue a packet and the queue already contains
	// MaxPendingQueueSize elements, then the packet will be rejected and should
	// not be forwarded.
	MaxPendingQueueSize uint8

	// Clock represents the clock that should be used to obtain the current time.
	//
	// This field is required and must have a non-nil value.
	Clock tcpip.Clock
}

Config represents the options for configuring a RouteTable.

+stateify savable

func DefaultConfig

func DefaultConfig(clock tcpip.Clock) Config

DefaultConfig returns the default configuration for the table.

type GetRouteResult

type GetRouteResult struct {
	// GetRouteResultState signals the result of calling GetRouteOrInsertPending.
	GetRouteResultState GetRouteResultState

	// InstalledRoute represents the existing installed route. This field will
	// only be populated if the GetRouteResultState is InstalledRouteFound.
	InstalledRoute *InstalledRoute
}

GetRouteResult represents the result of calling GetRouteOrInsertPending.

type GetRouteResultState

type GetRouteResultState uint8

GetRouteResultState signals the result of calling GetRouteOrInsertPending.

const (
	// InstalledRouteFound indicates that an InstalledRoute was found.
	InstalledRouteFound GetRouteResultState = iota

	// PacketQueuedInPendingRoute indicates that the packet was queued in an
	// existing pending route.
	PacketQueuedInPendingRoute

	// NoRouteFoundAndPendingInserted indicates that no route was found and that
	// a pending route was newly inserted into the RouteTable.
	NoRouteFoundAndPendingInserted
)

func (GetRouteResultState) String

func (e GetRouteResultState) String() string

type InstalledRoute

type InstalledRoute struct {
	stack.MulticastRoute
	// contains filtered or unexported fields
}

InstalledRoute represents a route that is in the installed state.

If a route is in the installed state, then it may be used to forward multicast packets.

+stateify savable

func (*InstalledRoute) LastUsedTimestamp

func (r *InstalledRoute) LastUsedTimestamp() tcpip.MonotonicTime

LastUsedTimestamp returns a monotonic timestamp that corresponds to the last time the route was used or updated.

func (*InstalledRoute) SetLastUsedTimestamp

func (r *InstalledRoute) SetLastUsedTimestamp(monotonicTime tcpip.MonotonicTime)

SetLastUsedTimestamp sets the time that the route was last used.

The timestamp is only updated if it occurs after the currently set timestamp. Callers should invoke this anytime the route is used to forward a packet.

type PendingRoute

type PendingRoute struct {
	// contains filtered or unexported fields
}

PendingRoute represents a route that is in the "pending" state.

A route is in the pending state if an installed route does not yet exist for the entry. For such routes, packets are added to an expiring queue until a route is installed.

+stateify savable

type RouteTable

type RouteTable struct {
	// contains filtered or unexported fields
}

RouteTable represents a multicast routing table.

+stateify savable

func (*RouteTable) AddInstalledRoute

AddInstalledRoute adds the provided route to the table.

Packets that were queued while the route was in the pending state are returned. The caller assumes ownership of these packets and is responsible for forwarding and releasing them. If an installed route already exists for the provided key, then it is overwritten.

func (*RouteTable) Close

func (r *RouteTable) Close()

Close cleans up resources held by the table.

Calling this will stop the cleanup routine and release any packets owned by the table.

func (*RouteTable) GetLastUsedTimestamp

GetLastUsedTimestamp returns a monotonic timestamp that represents the last time the route that matches the provided key was used or updated.

Returns true if a matching route was found. Otherwise returns false.

func (*RouteTable) GetRouteOrInsertPending

GetRouteOrInsertPending attempts to fetch the installed route that matches the provided key.

If no matching installed route is found, then the pkt is cloned and queued in a pending route. The GetRouteResult.GetRouteResultState will indicate whether the pkt was queued in a new pending route or an existing one.

If the relevant pending route queue is at max capacity, then returns false. Otherwise, returns true.

func (*RouteTable) Init

func (r *RouteTable) Init(config Config) error

Init initializes the RouteTable with the provided config.

An error is returned if the config is not valid.

Must be called before any other function on the table.

func (*RouteTable) NewInstalledRoute

func (r *RouteTable) NewInstalledRoute(route stack.MulticastRoute) *InstalledRoute

NewInstalledRoute instantiates an installed route for the table.

func (*RouteTable) RemoveAllInstalledRoutes

func (r *RouteTable) RemoveAllInstalledRoutes()

RemoveAllInstalledRoutes removes all installed routes from the table.

func (*RouteTable) RemoveInstalledRoute

func (r *RouteTable) RemoveInstalledRoute(key stack.UnicastSourceAndMulticastDestination) bool

RemoveInstalledRoute deletes any installed route that matches the provided key.

Returns true if a route was removed. Otherwise returns false.

Jump to

Keyboard shortcuts

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