github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/cmd/examples/test_xdp_program/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/dylandreimerink/gobpfld"
     9  	"github.com/dylandreimerink/gobpfld/bpftypes"
    10  	"github.com/dylandreimerink/gobpfld/ebpf"
    11  )
    12  
    13  // To demonstrate the testing feature, a small program is used that blocks all IPv6 traffic.
    14  
    15  func main() {
    16  	program := &gobpfld.ProgramXDP{
    17  		AbstractBPFProgram: gobpfld.AbstractBPFProgram{
    18  			Name:        gobpfld.MustNewObjName("block_ipv6"),
    19  			ProgramType: bpftypes.BPF_PROG_TYPE_XDP,
    20  			License:     "GPL",
    21  		},
    22  	}
    23  
    24  	asm := `
    25  		r0 = 2 						# 2 = XDP_PASS
    26  		r2 = *(u32 *)(r1 + 4) 		# r2 = xdp_md.data_end
    27  		r1 = *(u32 *)(r1 + 0)		# r1 = xdp_md.data
    28  		r1 += 12					# EthType is at offset 12
    29  		r3 = r1						# Use r3 for bounds checking
    30  		r3 += 2						# Add 2 since we want to read 2 bytes (u16)
    31  		if r3 > r2 goto return  	# If there are less than 14 bytes, pass the packet (bounds check)
    32  		r1 = *(u16 *)(r1 + 0)   	# Read EthType from frame
    33  		if r1 != 0xDD86 goto return	# If 86DD = IPv6, reversed due to network byte order
    34  		r0 = 1						# 1 = XDP_DROP
    35  	return:
    36  		exit
    37  	`
    38  
    39  	inst, err := ebpf.AssemblyToInstructions("inline-asm", strings.NewReader(asm))
    40  	if err != nil {
    41  		panic(err)
    42  	}
    43  
    44  	program.Instructions = ebpf.MustEncode(inst)
    45  
    46  	log, err := program.Load(gobpfld.ProgXDPLoadOpts{
    47  		VerifierLogLevel: bpftypes.BPFLogLevelBasic,
    48  	})
    49  
    50  	fmt.Printf("BPF Verifier log:\n%s\n", log)
    51  
    52  	if err != nil {
    53  		err2 := program.DecodeToReader(os.Stdout)
    54  		if err2 != nil {
    55  			fmt.Fprintf(os.Stderr, "error while decoding program: %s\n", err.Error())
    56  		}
    57  		fmt.Fprintf(os.Stderr, "error while loading program: %s\n", err.Error())
    58  		os.Exit(1)
    59  	}
    60  
    61  	ret, err := program.XDPTestProgram(gobpfld.TestXDPProgSettings{
    62  		Data: []byte{
    63  			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // SRC MAC
    64  			0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, // DST MAC
    65  			0x86, 0xDD, // EthType = IPv6
    66  			0x00, 0x00,
    67  		},
    68  		Repeat: 1000,
    69  	})
    70  	if err != nil {
    71  		fmt.Fprintf(os.Stderr, "error while testing program: %s\n", err.Error())
    72  		os.Exit(1)
    73  	}
    74  
    75  	fmt.Fprintf(os.Stdout, "Duration: %d, return value: %d\n", ret.Duration, ret.ReturnValue)
    76  
    77  	ret, err = program.XDPTestProgram(gobpfld.TestXDPProgSettings{
    78  		Data: []byte{
    79  			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // SRC MAC
    80  			0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, // DST MAC
    81  			0x08, 0x00, // EthType = IPv4
    82  			0x00, 0x00,
    83  		},
    84  		Repeat: 1000,
    85  	})
    86  	if err != nil {
    87  		fmt.Fprintf(os.Stderr, "error while testing program: %s\n", err.Error())
    88  		os.Exit(1)
    89  	}
    90  
    91  	fmt.Fprintf(os.Stdout, "Duration: %d, return value: %d\n", ret.Duration, ret.ReturnValue)
    92  }