func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
	req := h.newNetlinkRequest(syscall.RTM_GETTFILTER, syscall.NLM_F_DUMP)
	msg := &nl.TcMsg{
		Family: nl.FAMILY_ALL,
		Parent: parent,
	}
	if link != nil {
		base := link.Attrs()
		h.ensureIndex(base)
		msg.Ifindex = int32(base.Index)
	}
	req.AddData(msg)
	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTFILTER)
	if err != nil {
		return nil, err
	}
	var res []Filter
	for _, m := range msgs {
		msg := nl.DeserializeTcMsg(m)
		attrs, err := nl.ParseRouteAttr(m[msg.Len():])
		if err != nil {
			return nil, err
		}
		base := FilterAttrs{
			LinkIndex: int(msg.Ifindex),
			Handle:    msg.Handle,
			Parent:    msg.Parent,
		}
		base.Priority, base.Protocol = MajorMinor(msg.Info)
		base.Protocol = nl.Swap16(base.Protocol)
		var filter Filter
		filterType := ""
		detailed := false
		for _, attr := range attrs {
			switch attr.Attr.Type {
			case nl.TCA_KIND:
				filterType = string(attr.Value[:len(attr.Value)-1])
				switch filterType {
				case "u32":
					filter = &U32{}
				case "fw":
					filter = &Fw{}
				case "bpf":
					filter = &BpfFilter{}
				default:
					filter = &GenericFilter{FilterType: filterType}
				}
			case nl.TCA_OPTIONS:
				data, err := nl.ParseRouteAttr(attr.Value)
				if err != nil {
					return nil, err
				}
				switch filterType {
				case "u32":
					detailed, err = parseU32Data(filter, data)
					if err != nil {
						return nil, err
					}
				case "fw":
					detailed, err = parseFwData(filter, data)
					if err != nil {
						return nil, err
					}
				case "bpf":
					detailed, err = parseBpfData(filter, data)
					if err != nil {
						return nil, err
					}
				default:
					detailed = true
				}
			}
		}
		if detailed {
			*filter.Attrs() = base
			res = append(res, filter)
		}
	}
	return res, nil
}
FilterList gets a list of filters in the system.
Equivalent to: `tc filter show`.
Generally returns nothing if link and parent are not specified.
package netlink
import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"syscall"
	"github.com/vishvananda/netlink/nl"
)
type Fw struct {
	FilterAttrs
	ClassId uint32
	Police nl.TcPolice
	InDev  string
	Mask   uint32
	AvRate uint32
	Rtab   [256]uint32
	Ptab   [256]uint32
}
func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
	var rtab [256]uint32
	var ptab [256]uint32
	rcellLog := -1
	pcellLog := -1
	avrate := fattrs.AvRate / 8
	police := nl.TcPolice{}
	police.Rate.Rate = fattrs.Rate / 8
	police.PeakRate.Rate = fattrs.PeakRate / 8
	buffer := fattrs.Buffer
	linklayer := nl.LINKLAYER_ETHERNET
	if fattrs.LinkLayer != nl.LINKLAYER_UNSPEC {
		linklayer = fattrs.LinkLayer
	}
	police.Action = int32(fattrs.Action)
	if police.Rate.Rate != 0 {
		police.Rate.Mpu = fattrs.Mpu
		police.Rate.Overhead = fattrs.Overhead
		if CalcRtable(&police.Rate, rtab, rcellLog, fattrs.Mtu, linklayer) < 0 {
			return nil, errors.New("TBF: failed to calculate rate table")
		}
		police.Burst = uint32(Xmittime(uint64(police.Rate.Rate), uint32(buffer)))
	}
	police.Mtu = fattrs.Mtu
	if police.PeakRate.Rate != 0 {
		police.PeakRate.Mpu = fattrs.Mpu
		police.PeakRate.Overhead = fattrs.Overhead
		if CalcRtable(&police.PeakRate, ptab, pcellLog, fattrs.Mtu, linklayer) < 0 {
			return nil, errors.New("POLICE: failed to calculate peak rate table")
		}
	}
	return &Fw{
		FilterAttrs: attrs,
		ClassId:     fattrs.ClassId,
		InDev:       fattrs.InDev,
		Mask:        fattrs.Mask,
		Police:      police,
		AvRate:      avrate,
		Rtab:        rtab,
		Ptab:        ptab,
	}, nil
}
func (filter *Fw) Attrs() *FilterAttrs {
	return &filter.FilterAttrs
}
func (filter *Fw) Type() string {
	return "fw"
}
func FilterDel(filter Filter) error {
	return pkgHandle.FilterDel(filter)
}
func (h *Handle) FilterDel(filter Filter) error {
	req := h.newNetlinkRequest(syscall.RTM_DELTFILTER, syscall.NLM_F_ACK)
	base := filter.Attrs()
	msg := &nl.TcMsg{
		Family:  nl.FAMILY_ALL,
		Ifindex: int32(base.LinkIndex),
		Handle:  base.Handle,
		Parent:  base.Parent,
		Info:    MakeHandle(base.Priority, nl.Swap16(base.Protocol)),
	}
	req.AddData(msg)
	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
	return err
}
func FilterAdd(filter Filter) error {
	return pkgHandle.FilterAdd(filter)
}
func (h *Handle) FilterAdd(filter Filter) error {
	native = nl.NativeEndian()
	req := h.newNetlinkRequest(syscall.RTM_NEWTFILTER, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
	base := filter.Attrs()
	msg := &nl.TcMsg{
		Family:  nl.FAMILY_ALL,
		Ifindex: int32(base.LinkIndex),
		Handle:  base.Handle,
		Parent:  base.Parent,
		Info:    MakeHandle(base.Priority, nl.Swap16(base.Protocol)),
	}
	req.AddData(msg)
	req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type())))
	options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
	if u32, ok := filter.(*U32); ok {
		sel := nl.TcU32Sel{
			Nkeys: 1,
			Flags: nl.TC_U32_TERMINAL,
		}
		sel.Keys = append(sel.Keys, nl.TcU32Key{})
		nl.NewRtAttrChild(options, nl.TCA_U32_SEL, sel.Serialize())
		if u32.ClassId != 0 {
			nl.NewRtAttrChild(options, nl.TCA_U32_CLASSID, nl.Uint32Attr(u32.ClassId))
		}
		actionsAttr := nl.NewRtAttrChild(options, nl.TCA_U32_ACT, nil)
		if u32.RedirIndex != 0 {
			u32.Actions = append([]Action{NewMirredAction(u32.RedirIndex)}, u32.Actions...)
		}
		if err := EncodeActions(actionsAttr, u32.Actions); err != nil {
			return err
		}
	} else if fw, ok := filter.(*Fw); ok {
		if fw.Mask != 0 {
			b := make([]byte, 4)
			native.PutUint32(b, fw.Mask)
			nl.NewRtAttrChild(options, nl.TCA_FW_MASK, b)
		}
		if fw.InDev != "" {
			nl.NewRtAttrChild(options, nl.TCA_FW_INDEV, nl.ZeroTerminated(fw.InDev))
		}
		if (fw.Police != nl.TcPolice{}) {
			police := nl.NewRtAttrChild(options, nl.TCA_FW_POLICE, nil)
			nl.NewRtAttrChild(police, nl.TCA_POLICE_TBF, fw.Police.Serialize())
			if (fw.Police.Rate != nl.TcRateSpec{}) {
				payload := SerializeRtab(fw.Rtab)
				nl.NewRtAttrChild(police, nl.TCA_POLICE_RATE, payload)
			}
			if (fw.Police.PeakRate != nl.TcRateSpec{}) {
				payload := SerializeRtab(fw.Ptab)
				nl.NewRtAttrChild(police, nl.TCA_POLICE_PEAKRATE, payload)
			}
		}
		if fw.ClassId != 0 {
			b := make([]byte, 4)
			native.PutUint32(b, fw.ClassId)
			nl.NewRtAttrChild(options, nl.TCA_FW_CLASSID, b)
		}
	} else if bpf, ok := filter.(*BpfFilter); ok {
		var bpfFlags uint32
		if bpf.ClassId != 0 {
			nl.NewRtAttrChild(options, nl.TCA_BPF_CLASSID, nl.Uint32Attr(bpf.ClassId))
		}
		if bpf.Fd >= 0 {
			nl.NewRtAttrChild(options, nl.TCA_BPF_FD, nl.Uint32Attr((uint32(bpf.Fd))))
		}
		if bpf.Name != "" {
			nl.NewRtAttrChild(options, nl.TCA_BPF_NAME, nl.ZeroTerminated(bpf.Name))
		}
		if bpf.DirectAction {
			bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
		}
		nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
	}
	req.AddData(options)
	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
	return err
}
func FilterList(link Link, parent uint32) ([]Filter, error) {
	return pkgHandle.FilterList(link, parent)
}