Documentation
¶
Overview ¶
Package ebpf is a toolkit for working with eBPF programs.
eBPF programs are small snippets of code which are executed directly in a VM in the Linux kernel, which makes them very fast and flexible. Many Linux subsystems now accept eBPF programs. This makes it possible to implement highly application specific logic inside the kernel, without having to modify the actual kernel itself.
This package is designed for long-running processes which want to use eBPF to implement part of their application logic. It has no run-time dependencies outside of the library and the Linux kernel itself. eBPF code should be compiled ahead of time using clang, and shipped with your application as any other resource.
This package doesn't include code required to attach eBPF to Linux subsystems, since this varies per subsystem.
Example (CustomMarshaler) ¶
ExampleMarshaler shows how to use custom encoding with map methods.
package main
import (
"encoding"
"fmt"
"strings"
)
// Assert that customEncoding implements the correct interfaces.
var (
_ encoding.BinaryMarshaler = (*customEncoding)(nil)
_ encoding.BinaryUnmarshaler = (*customEncoding)(nil)
)
type customEncoding struct {
data string
}
func (ce *customEncoding) MarshalBinary() ([]byte, error) {
return []byte(strings.ToUpper(ce.data)), nil
}
func (ce *customEncoding) UnmarshalBinary(buf []byte) error {
ce.data = string(buf)
return nil
}
// ExampleMarshaler shows how to use custom encoding with map methods.
func main() {
hash := createHash()
defer hash.Close()
if err := hash.Put(&customEncoding{"hello"}, uint32(111)); err != nil {
panic(err)
}
var (
key customEncoding
value uint32
entries = hash.Iterate()
)
for entries.Next(&key, &value) {
fmt.Printf("key: %s, value: %d\n", key.data, value)
}
if err := entries.Err(); err != nil {
panic(err)
}
}
Output: key: HELLO, value: 111
Example (ExtractDistance) ¶
ExampleExtractDistance shows how to attach an eBPF socket filter to extract the network distance of an IP host.
package main
// This code is derived from https://github.com/cloudflare/cloudflare-blog/tree/master/2018-03-ebpf
//
// Copyright (c) 2015-2017 Cloudflare, Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of the Cloudflare, Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import (
"fmt"
"net"
"syscall"
"github.com/DataDog/ebpf"
"github.com/DataDog/ebpf/asm"
)
// ExampleExtractDistance shows how to attach an eBPF socket filter to
// extract the network distance of an IP host.
func main() {
filter, TTLs, err := newDistanceFilter()
if err != nil {
panic(err)
}
defer filter.Close()
defer TTLs.Close()
// Attach filter before the call to connect()
dialer := net.Dialer{
Control: func(network, address string, c syscall.RawConn) (err error) {
const SO_ATTACH_BPF = 50
err = c.Control(func(fd uintptr) {
err = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, SO_ATTACH_BPF, filter.FD())
})
return err
},
}
conn, err := dialer.Dial("tcp", "1.1.1.1:53")
if err != nil {
panic(err)
}
conn.Close()
minDist, err := minDistance(TTLs)
if err != nil {
panic(err)
}
fmt.Println("1.1.1.1:53 is", minDist, "hops away")
}
func newDistanceFilter() (*ebpf.Program, *ebpf.Map, error) {
const ETH_P_IPV6 uint16 = 0x86DD
ttls, err := ebpf.NewMap(&ebpf.MapSpec{
Type: ebpf.Hash,
KeySize: 4,
ValueSize: 8,
MaxEntries: 4,
})
if err != nil {
return nil, nil, err
}
insns := asm.Instructions{
// r1 has ctx
// r0 = ctx[16] (aka protocol)
asm.LoadMem(asm.R0, asm.R1, 16, asm.Word),
// Perhaps ipv6
asm.LoadImm(asm.R2, int64(ETH_P_IPV6), asm.DWord),
asm.HostTo(asm.BE, asm.R2, asm.Half),
asm.JEq.Reg(asm.R0, asm.R2, "ipv6"),
// otherwise assume ipv4
// 8th byte in IPv4 is TTL
// LDABS requires ctx in R6
asm.Mov.Reg(asm.R6, asm.R1),
asm.LoadAbs(-0x100000+8, asm.Byte),
asm.Ja.Label("store-ttl"),
// 7th byte in IPv6 is Hop count
// LDABS requires ctx in R6
asm.Mov.Reg(asm.R6, asm.R1).Sym("ipv6"),
asm.LoadAbs(-0x100000+7, asm.Byte),
// stash the load result into FP[-4]
asm.StoreMem(asm.RFP, -4, asm.R0, asm.Word).Sym("store-ttl"),
// stash the &FP[-4] into r2
asm.Mov.Reg(asm.R2, asm.RFP),
asm.Add.Imm(asm.R2, -4),
// r1 must point to map
asm.LoadMapPtr(asm.R1, ttls.FD()),
asm.FnMapLookupElem.Call(),
// load ok? inc. Otherwise? jmp to mapupdate
asm.JEq.Imm(asm.R0, 0, "update-map"),
asm.Mov.Imm(asm.R1, 1),
asm.StoreXAdd(asm.R0, asm.R1, asm.DWord),
asm.Ja.Label("exit"),
// MapUpdate
// r1 has map ptr
asm.LoadMapPtr(asm.R1, ttls.FD()).Sym("update-map"),
// r2 has key -> &FP[-4]
asm.Mov.Reg(asm.R2, asm.RFP),
asm.Add.Imm(asm.R2, -4),
// r3 has value -> &FP[-16] , aka 1
asm.StoreImm(asm.RFP, -16, 1, asm.DWord),
asm.Mov.Reg(asm.R3, asm.RFP),
asm.Add.Imm(asm.R3, -16),
// r4 has flags, 0
asm.Mov.Imm(asm.R4, 0),
asm.FnMapUpdateElem.Call(),
// set exit code to -1, don't trunc packet
asm.Mov.Imm(asm.R0, -1).Sym("exit"),
asm.Return(),
}
prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
Name: "distance_filter",
Type: ebpf.SocketFilter,
License: "GPL",
Instructions: insns,
})
if err != nil {
ttls.Close()
return nil, nil, err
}
return prog, ttls, nil
}
func minDistance(TTLs *ebpf.Map) (int, error) {
var (
entries = TTLs.Iterate()
ttl uint32
minDist uint32 = 255
count uint64
)
for entries.Next(&ttl, &count) {
var dist uint32
switch {
case ttl > 128:
dist = 255 - ttl
case ttl > 64:
dist = 128 - ttl
case ttl > 32:
dist = 64 - ttl
default:
dist = 32 - ttl
}
if minDist > dist {
minDist = dist
}
}
return int(minDist), entries.Err()
}
Output:
Example (Program) ¶
Example_program demonstrates how to attach an eBPF program to a tracepoint. The program will be attached to the sys_enter_open syscall and print out the integer 123 everytime the sycall is used.
//go:build linux
// +build linux
package main
import (
"context"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
"time"
"github.com/DataDog/ebpf"
"github.com/DataDog/ebpf/asm"
"github.com/DataDog/ebpf/perf"
"golang.org/x/sys/unix"
)
// getTracepointID returns the system specific ID for the tracepoint sys_enter_open.
func getTracepointID() (uint64, error) {
data, err := ioutil.ReadFile("/sys/kernel/debug/tracing/events/syscalls/sys_enter_open/id")
if err != nil {
return 0, fmt.Errorf("failed to read tracepoint ID for 'sys_enter_open': %v", err)
}
tid := strings.TrimSuffix(string(data), "\n")
return strconv.ParseUint(tid, 10, 64)
}
// Example_program demonstrates how to attach an eBPF program to a tracepoint.
// The program will be attached to the sys_enter_open syscall and print out the integer
// 123 everytime the sycall is used.
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
events, err := ebpf.NewMap(&ebpf.MapSpec{
Type: ebpf.PerfEventArray,
Name: "pureGo",
})
if err != nil {
panic(fmt.Errorf("could not create event map: %v\n", err))
}
defer events.Close()
rd, err := perf.NewReader(events, os.Getpagesize())
if err != nil {
panic(fmt.Errorf("could not create event reader: %v", err))
}
defer rd.Close()
go func() {
for {
select {
case <-ctx.Done():
return
default:
}
record, err := rd.Read()
if err != nil {
if perf.IsClosed(err) {
return
}
panic(fmt.Errorf("could not read from reader: %v", err))
}
fmt.Println(record)
}
}()
ins := asm.Instructions{
// store the integer 123 at FP[-8]
asm.Mov.Imm(asm.R2, 123),
asm.StoreMem(asm.RFP, -8, asm.R2, asm.Word),
// load registers with arguments for call of FnPerfEventOutput
asm.LoadMapPtr(asm.R2, events.FD()),
asm.LoadImm(asm.R3, 0xffffffff, asm.DWord),
asm.Mov.Reg(asm.R4, asm.RFP),
asm.Add.Imm(asm.R4, -8),
asm.Mov.Imm(asm.R5, 4),
// call FnPerfEventOutput
asm.FnPerfEventOutput.Call(),
// set exit code to 0
asm.Mov.Imm(asm.R0, 0),
asm.Return(),
}
prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
Name: "sys_enter_open",
Type: ebpf.TracePoint,
License: "GPL",
Instructions: ins,
})
if err != nil {
panic(fmt.Errorf("could not create new ebpf program: %v", err))
}
defer prog.Close()
tid, err := getTracepointID()
if err != nil {
panic(fmt.Errorf("could not get tracepoint id: %v", err))
}
attr := unix.PerfEventAttr{
Type: unix.PERF_TYPE_TRACEPOINT,
Config: tid,
Sample_type: unix.PERF_SAMPLE_RAW,
Sample: 1,
Wakeup: 1,
}
pfd, err := unix.PerfEventOpen(&attr, -1, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
if err != nil {
panic(fmt.Errorf("unable to open perf events: %v", err))
}
if _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(pfd), unix.PERF_EVENT_IOC_ENABLE, 0); errno != 0 {
panic(fmt.Errorf("unable to enable perf events: %v", err))
}
if _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(pfd), unix.PERF_EVENT_IOC_SET_BPF, uintptr(prog.FD())); errno != 0 {
panic(fmt.Errorf("unable to attach bpf program to perf events: %v", err))
}
<-ctx.Done()
if _, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(pfd), unix.PERF_EVENT_IOC_DISABLE, 0); errno != 0 {
panic(fmt.Errorf("unable to disable perf events: %v", err))
}
}
Output:
Example (SocketELF) ¶
ExampleSocketELF demonstrates how to load an eBPF program from an ELF, and attach it to a raw socket.
//go:build linux
// +build linux
package main
import (
"bytes"
"flag"
"fmt"
"syscall"
"time"
"github.com/DataDog/ebpf"
)
var program = [...]byte{
0177, 0105, 0114, 0106, 0002, 0001, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0001, 0000, 0367, 0000, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0340, 0001, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0100, 0000, 0000, 0000, 0000, 0000, 0100, 0000, 0010, 0000, 0001, 0000,
0277, 0026, 0000, 0000, 0000, 0000, 0000, 0000, 0060, 0000, 0000, 0000, 0027, 0000, 0000, 0000,
0143, 0012, 0374, 0377, 0000, 0000, 0000, 0000, 0141, 0141, 0004, 0000, 0000, 0000, 0000, 0000,
0125, 0001, 0010, 0000, 0004, 0000, 0000, 0000, 0277, 0242, 0000, 0000, 0000, 0000, 0000, 0000,
0007, 0002, 0000, 0000, 0374, 0377, 0377, 0377, 0030, 0001, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0205, 0000, 0000, 0000, 0001, 0000, 0000, 0000,
0025, 0000, 0002, 0000, 0000, 0000, 0000, 0000, 0141, 0141, 0000, 0000, 0000, 0000, 0000, 0000,
0333, 0020, 0000, 0000, 0000, 0000, 0000, 0000, 0267, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0225, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0002, 0000, 0000, 0000, 0004, 0000, 0000, 0000,
0010, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0000, 0000, 0000, 0002, 0000, 0000, 0000,
0004, 0000, 0000, 0000, 0010, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0000, 0000, 0000,
0107, 0120, 0114, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0065, 0000, 0000, 0000, 0000, 0000, 0003, 0000, 0150, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0034, 0000, 0000, 0000, 0020, 0000, 0006, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0110, 0000, 0000, 0000, 0020, 0000, 0003, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0014, 0000, 0000, 0000, 0020, 0000, 0005, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0023, 0000, 0000, 0000, 0020, 0000, 0005, 0000, 0024, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0070, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0001, 0000, 0000, 0000, 0004, 0000, 0000, 0000, 0000, 0056, 0164, 0145, 0170, 0164, 0000, 0155,
0141, 0160, 0163, 0000, 0155, 0171, 0137, 0155, 0141, 0160, 0000, 0164, 0145, 0163, 0164, 0137,
0155, 0141, 0160, 0000, 0137, 0154, 0151, 0143, 0145, 0156, 0163, 0145, 0000, 0056, 0163, 0164,
0162, 0164, 0141, 0142, 0000, 0056, 0163, 0171, 0155, 0164, 0141, 0142, 0000, 0114, 0102, 0102,
0060, 0137, 0063, 0000, 0056, 0162, 0145, 0154, 0163, 0157, 0143, 0153, 0145, 0164, 0061, 0000,
0142, 0160, 0146, 0137, 0160, 0162, 0157, 0147, 0061, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0045, 0000, 0000, 0000, 0003, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0210, 0001, 0000, 0000, 0000, 0000, 0000, 0000,
0122, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0001, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0001, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0006, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0100, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0004, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0100, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0006, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0100, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0170, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0010, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0074, 0000, 0000, 0000, 0011, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0170, 0001, 0000, 0000, 0000, 0000, 0000, 0000,
0020, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0007, 0000, 0000, 0000, 0003, 0000, 0000, 0000,
0010, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0020, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0007, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0003, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0270, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0050, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0004, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0035, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0003, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0340, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0004, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0001, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0055, 0000, 0000, 0000, 0002, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0350, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
0220, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0001, 0000, 0000, 0000, 0002, 0000, 0000, 0000,
0010, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0030, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
}
// ExampleSocketELF demonstrates how to load an eBPF program from an ELF,
// and attach it to a raw socket.
func main() {
const SO_ATTACH_BPF = 50
index := flag.Int("index", 0, "specify ethernet index")
flag.Parse()
spec, err := ebpf.LoadCollectionSpecFromReader(bytes.NewReader(program[:]))
if err != nil {
panic(err)
}
coll, err := ebpf.NewCollection(spec)
if err != nil {
panic(err)
}
defer coll.Close()
sock, err := openRawSock(*index)
if err != nil {
panic(err)
}
defer syscall.Close(sock)
prog := coll.DetachProgram("bpf_prog1")
if prog == nil {
panic("no program named bpf_prog1 found")
}
defer prog.Close()
if err := syscall.SetsockoptInt(sock, syscall.SOL_SOCKET, SO_ATTACH_BPF, prog.FD()); err != nil {
panic(err)
}
fmt.Printf("Filtering on eth index: %d\n", *index)
fmt.Println("Packet stats:")
protoStats := coll.DetachMap("my_map")
if protoStats == nil {
panic(fmt.Errorf("no map named my_map found"))
}
defer protoStats.Close()
for {
const (
ICMP = 0x01
TCP = 0x06
UDP = 0x11
)
time.Sleep(time.Second)
var icmp uint64
var tcp uint64
var udp uint64
err := protoStats.Lookup(uint32(ICMP), &icmp)
if err != nil {
panic(err)
}
err = protoStats.Lookup(uint32(TCP), &tcp)
if err != nil {
panic(err)
}
err = protoStats.Lookup(uint32(UDP), &udp)
if err != nil {
panic(err)
}
fmt.Printf("\r\033[m\tICMP: %d TCP: %d UDP: %d", icmp, tcp, udp)
}
}
func openRawSock(index int) (int, error) {
const ETH_P_ALL uint16 = 0x00<<8 | 0x03
sock, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, int(ETH_P_ALL))
if err != nil {
return 0, err
}
sll := syscall.SockaddrLinklayer{}
sll.Protocol = ETH_P_ALL
sll.Ifindex = index
if err := syscall.Bind(sock, &sll); err != nil {
return 0, err
}
return sock, nil
}
Output:
Index ¶
- Constants
- Variables
- func CurrentKernelVersion() (uint32, error)
- func KernelVersionFromReleaseString(releaseString string) (uint32, error)
- func SanitizeName(name string, replacement rune) string
- type AttachFlags
- type AttachType
- type Collection
- type CollectionOptions
- type CollectionSpec
- type Map
- func (m *Map) ABI() MapABI
- func (m *Map) Clone() (*Map, error)
- func (m *Map) Close() error
- func (m *Map) Delete(key interface{}) error
- func (m *Map) FD() int
- func (m *Map) Freeze() error
- func (m *Map) ID() (MapID, error)
- func (m *Map) Iterate() *MapIterator
- func (m *Map) IterateFrom(prevKey interface{}) *MapIterator
- func (m *Map) Lookup(key, valueOut interface{}) error
- func (m *Map) LookupAndDelete(key, valueOut interface{}) error
- func (m *Map) LookupBytes(key interface{}) ([]byte, error)
- func (m *Map) MarshalBinary() ([]byte, error)
- func (m *Map) NextKey(key, nextKeyOut interface{}) error
- func (m *Map) NextKeyBytes(key interface{}) ([]byte, error)
- func (m *Map) Pin(fileName string) error
- func (m *Map) Put(key, value interface{}) error
- func (m *Map) String() string
- func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error
- type MapABI
- type MapID
- type MapIterator
- type MapKV
- type MapSpec
- type MapType
- type MapUpdateFlags
- type Program
- func LoadPinnedProgram(fileName string) (*Program, error)
- func LoadPinnedProgramExplicit(fileName string, abi *ProgramABI) (*Program, error)
- func NewProgram(spec *ProgramSpec) (*Program, error)
- func NewProgramFromFD(fd int) (*Program, error)
- func NewProgramFromID(id ProgramID) (*Program, error)
- func NewProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, error)
- func (p *Program) ABI() ProgramABI
- func (p *Program) Attach(fd int, typ AttachType, flags AttachFlags) error
- func (p *Program) Benchmark(in []byte, repeat int, reset func()) (uint32, time.Duration, error)
- func (p *Program) Clone() (*Program, error)
- func (p *Program) Close() error
- func (p *Program) Detach(fd int, typ AttachType, flags AttachFlags) error
- func (p *Program) FD() int
- func (p *Program) ID() (ProgramID, error)
- func (p *Program) MarshalBinary() ([]byte, error)
- func (p *Program) Pin(fileName string) error
- func (p *Program) String() string
- func (p *Program) Test(in []byte) (uint32, []byte, error)
- type ProgramABI
- type ProgramID
- type ProgramOptions
- type ProgramSpec
- type ProgramType
Examples ¶
Constants ¶
const DefaultVerifierLogSize = 64 * 1024
DefaultVerifierLogSize is the default number of bytes allocated for the verifier log.
Variables ¶
var ( ErrKeyNotExist = errors.New("key does not exist") ErrKeyExist = errors.New("key already exists") ErrIterationAborted = errors.New("iteration aborted") )
Errors returned by Map and MapIterator methods.
var (
ErrNotExist = errors.New("requested object does not exit")
)
Generic errors returned by BPF syscalls.
var ErrNotSupported = internal.ErrNotSupported
ErrNotSupported is returned whenever the kernel doesn't support a feature.
Functions ¶
func CurrentKernelVersion ¶
CurrentKernelVersion returns the current kernel version in LINUX_VERSION_CODE format (see KernelVersionFromReleaseString())
func KernelVersionFromReleaseString ¶
KernelVersionFromReleaseString converts a release string with format 4.4.2[-1] to a kernel version number in LINUX_VERSION_CODE format. That is, for kernel "a.b.c", the version number will be (a<<16 + b<<8 + c)
func SanitizeName ¶
SanitizeName replaces all invalid characters in name.
Use this to automatically generate valid names for maps and programs at run time.
Passing a negative value for replacement will delete characters instead of replacing them.