github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/cmd/testsuite/integration/xdp_stats_test.go (about)

     1  //go:build bpftests
     2  // +build bpftests
     3  
     4  package integration
     5  
     6  import (
     7  	"bytes"
     8  	"net"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/dylandreimerink/gobpfld"
    13  	"github.com/dylandreimerink/gobpfld/bpftypes"
    14  )
    15  
    16  // This example command is a pure go replacement for the userpace program of the Basic03 program from
    17  // xdp-tutorial. https://github.com/xdp-project/xdp-tutorial/tree/master/basic03-map-counter
    18  // This example has no options but does demonstrate program loading from ELF, attaching to a interface, and interacting with a map
    19  func TestIntegrationXDPstats(t *testing.T) {
    20  	elfFileBytes, err := ebpf.ReadFile("ebpf/xdp_stats_test")
    21  	if err != nil {
    22  		t.Fatal(err)
    23  	}
    24  
    25  	elf, err := gobpfld.LoadProgramFromELF(bytes.NewReader(elfFileBytes), gobpfld.ELFParseSettings{})
    26  	if err != nil {
    27  		t.Fatal(err)
    28  	}
    29  
    30  	program := elf.Programs["xdp_stats1_func"].(*gobpfld.ProgramXDP)
    31  
    32  	// All maps loaded from elf files are BPFGenericMaps
    33  	statsMap := program.Maps["xdp_stats_map"].(*gobpfld.ArrayMap)
    34  
    35  	log, err := program.Load(gobpfld.ProgXDPLoadOpts{
    36  		VerifierLogLevel: bpftypes.BPFLogLevelBasic,
    37  	})
    38  	if err != nil {
    39  		t.Log(log)
    40  		t.Fatal(err)
    41  	}
    42  
    43  	err = program.Attach(gobpfld.ProgXDPAttachOpts{
    44  		InterfaceName: "lo",
    45  		Replace:       true,
    46  	})
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  
    51  	detach := func() {
    52  		err = program.XDPLinkDetach(gobpfld.BPFProgramXDPLinkDetachSettings{
    53  			All: true,
    54  		})
    55  		if err != nil {
    56  			t.Fatal(err)
    57  		}
    58  	}
    59  	defer detach()
    60  
    61  	udpConn, err := net.Dial("udp", "127.0.0.1:123")
    62  	if err != nil {
    63  		t.Fatal(err)
    64  	}
    65  
    66  	// Write some bogus UDP packets to localhost to generate traffic
    67  	ticker := time.Tick(1 * time.Second)
    68  	endTimer := time.NewTimer(5 * time.Second)
    69  	stop := false
    70  	for !stop {
    71  		select {
    72  		case <-ticker:
    73  			udpConn.Write([]byte("Hello World"))
    74  
    75  		case <-endTimer.C:
    76  			stop = true
    77  		}
    78  	}
    79  
    80  	// The key is 2 since the program puts stats in the XDP_PASS key which has value 2
    81  	// Tho this is specific to the XDP program we are using as an example.
    82  	var value int64
    83  	err = statsMap.Get(2, &value)
    84  	if err != nil {
    85  		t.Fatal(err)
    86  	}
    87  
    88  	if value == 0 {
    89  		t.Fatal("Expected at least one packet")
    90  	}
    91  }