func (p *Prog) DetachFromSocket(sock Socket) error {
	if p.pfd == nil {
		return errProgNotLoaded
	}
	var err error
	cerr := sock.Control(func(fd uintptr) {
		err = p.pfd.DetachFromSocket(int(fd))
	})
	if cerr != nil {
		return cerr
	}
	return err
}
DetachFromSocket detaches the program from the specified socket.
package ebpf
import (
	"errors"
	"unsafe"
	"golang.org/x/sys/unix"
)
type ProgType uint32
const (
	ProgTypeUnspec ProgType = iota
	ProgTypeSocketFilter
	ProgTypeKProbe
	ProgTypeSchedCLS
	ProgTypeSchedACT
	ProgTypeTracepoint
	ProgTypeXDP
	ProgTypePerfEvent
	ProgTypeCGroupSKB
	ProgTypeCGroupSock
	ProgTypeLWTIn
	ProgTypeLWTOut
	ProgTypeLWTXMit
	ProgTypeSockOps
	ProgTypeSKSKB
	ProgTypeCGroupDevice
	ProgTypeSKMsg
	ProgTypeRawTracepoint
	ProgTypeCGroupSockAddr
	ProgTypeLWTSeg6Local
	ProgTypeLIRCMode2
	ProgTypeSKReusePort
)
type AttachType uint32
const (
	AttachTypeCGroupInetIngress AttachType = iota
	AttachTypeCGroupInetEgress
	AttachTypeCGroupInetSockCreate
	AttachTypeCGroupSockOps
	AttachTypeSKSKBStreamParser
	AttachTypeSKSKBStreamVerdict
	AttachTypeCGroupDevice
	AttachTypeSKMsgVerdict
	AttachTypeCGroupInet4Bind
	AttachTypeCGroupInet6Bind
	AttachTypeCGroupInet4Connect
	AttachTypeCGroupInet6Connect
	AttachTypeCGroupInet4PostBind
	AttachTypeCGroupInet6PostBind
	AttachTypeCGroupUDP4SendMsg
	AttachTypeCGroupUDP6SendMsg
	AttachTypeLIRCMode2
)
type Prog struct {
	Type               ProgType
	License            string
	KernelVersion      uint32
	StrictAlignment    bool
	ObjectName         string
	IfIndex            uint32
	ExpectedAttachType AttachType
	pfd *progFD
}
const defaultLogBufSize = 256 * 1024
const loadStrictAlignment = 1 << 0
type CGroupAttachFlag uint32
const (
	CGroupAttachAllowNone CGroupAttachFlag = 0
	CGroupAttachAllowOverride CGroupAttachFlag = 1 << 0
	CGroupAttachAllowMulti CGroupAttachFlag = 1 << 1
)
func (p *Prog) Load(s *InstructionStream) (log string, err error) {
	if s.empty() {
		return "", errors.New("ebpf: empty instruction stream")
	}
	if s.hasUnresolvedSymbols() {
		return "", errors.New("ebpf: unresolved symbols in instruction stream")
	}
	insns := s.instructions()
	logbuf := make([]byte, defaultLogBufSize)
	attr := progLoadAttr{
		Type:               p.Type,
		InstructionCount:   uint32(len(insns)),
		Instructions:       iptr(insns),
		License:            bptr(nullTerminatedString(p.License)),
		LogLevel:           1,
		LogBufSize:         uint32(len(logbuf)),
		LogBuf:             bptr(logbuf),
		KernelVersion:      p.KernelVersion,
		Name:               newObjectName(p.ObjectName),
		IfIndex:            p.IfIndex,
		ExpectedAttachType: p.ExpectedAttachType,
	}
	if p.StrictAlignment {
		attr.Flags = loadStrictAlignment
	}
	pfd := new(progFD)
	err = pfd.Init(&attr)
	for i := 0; i < len(logbuf); i++ {
		if logbuf[i] == 0 {
			log = string(logbuf[:i])
			break
		}
	}
	if err != nil {
		return log, err
	}
	p.pfd = pfd
	return log, nil
}
type Socket interface {
	Control(fn func(fd uintptr)) error
}
type RawSocketFD int
func (raw RawSocketFD) Control(fn func(fd uintptr)) error {
	fn(uintptr(raw))
	return nil
}
var errProgNotLoaded = errors.New("ebpf: program not loaded")
func (p *Prog) AttachToSocket(sock Socket) error {
	if p.pfd == nil {
		return errProgNotLoaded
	}
	var err error
	cerr := sock.Control(func(fd uintptr) {
		err = p.pfd.AttachToSocket(int(fd))
	})
	if cerr != nil {
		return cerr
	}
	return err
}
func (p *Prog) AttachToCGroup(fd int, typ AttachType, flag CGroupAttachFlag) error {
	return errNotImplemented
}