mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
PacketBufferPtr is leftover from a dead experiment. Just use *PacketBuffer. PiperOrigin-RevId: 611531815
141 lines
4.1 KiB
Go
141 lines
4.1 KiB
Go
// Copyright 2022 The gVisor Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package multicast_test
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"gvisor.dev/gvisor/pkg/buffer"
|
|
"gvisor.dev/gvisor/pkg/refs"
|
|
"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
|
|
defaultMTU = 1500
|
|
inputNICID tcpip.NICID = 1
|
|
outgoingNICID tcpip.NICID = 2
|
|
)
|
|
|
|
// Example shows how to interact with a multicast RouteTable.
|
|
func Example() {
|
|
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))
|
|
}
|
|
|
|
// Output:
|
|
// emitMissingRouteEvent
|
|
// deliverPktLocally
|
|
// forwardPkt
|
|
// Last used timestamp: 10000000000
|
|
}
|
|
|
|
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)),
|
|
})
|
|
}
|
|
|
|
func TestMain(m *testing.M) {
|
|
refs.SetLeakMode(refs.LeaksPanic)
|
|
code := m.Run()
|
|
refs.DoLeakCheck()
|
|
os.Exit(code)
|
|
}
|