mirror of https://github.com/vishvananda/netlink
Add Matchall filter
This commit is contained in:
parent
7b4c06360e
commit
1882fa99fc
15
filter.go
15
filter.go
|
@ -225,6 +225,21 @@ func (filter *U32) Type() string {
|
||||||
return "u32"
|
return "u32"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MatchAll filters match all packets
|
||||||
|
type MatchAll struct {
|
||||||
|
FilterAttrs
|
||||||
|
ClassId uint32
|
||||||
|
Actions []Action
|
||||||
|
}
|
||||||
|
|
||||||
|
func (filter *MatchAll) Attrs() *FilterAttrs {
|
||||||
|
return &filter.FilterAttrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (filter *MatchAll) Type() string {
|
||||||
|
return "matchall"
|
||||||
|
}
|
||||||
|
|
||||||
type FilterFwAttrs struct {
|
type FilterFwAttrs struct {
|
||||||
ClassId uint32
|
ClassId uint32
|
||||||
InDev string
|
InDev string
|
||||||
|
|
|
@ -222,6 +222,14 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
||||||
bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
|
bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
|
||||||
}
|
}
|
||||||
nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
|
nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
|
||||||
|
case *MatchAll:
|
||||||
|
actionsAttr := nl.NewRtAttrChild(options, nl.TCA_MATCHALL_ACT, nil)
|
||||||
|
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if filter.ClassId != 0 {
|
||||||
|
nl.NewRtAttrChild(options, nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
req.AddData(options)
|
req.AddData(options)
|
||||||
|
@ -288,6 +296,8 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||||
filter = &Fw{}
|
filter = &Fw{}
|
||||||
case "bpf":
|
case "bpf":
|
||||||
filter = &BpfFilter{}
|
filter = &BpfFilter{}
|
||||||
|
case "matchall":
|
||||||
|
filter = &MatchAll{}
|
||||||
default:
|
default:
|
||||||
filter = &GenericFilter{FilterType: filterType}
|
filter = &GenericFilter{FilterType: filterType}
|
||||||
}
|
}
|
||||||
|
@ -312,6 +322,11 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
case "matchall":
|
||||||
|
detailed, err = parseMatchAllData(filter, data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
detailed = true
|
detailed = true
|
||||||
}
|
}
|
||||||
|
@ -541,6 +556,28 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
|
||||||
return detailed, nil
|
return detailed, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
|
||||||
|
native = nl.NativeEndian()
|
||||||
|
matchall := filter.(*MatchAll)
|
||||||
|
detailed := true
|
||||||
|
for _, datum := range data {
|
||||||
|
switch datum.Attr.Type {
|
||||||
|
case nl.TCA_MATCHALL_CLASSID:
|
||||||
|
matchall.ClassId = native.Uint32(datum.Value[0:4])
|
||||||
|
case nl.TCA_MATCHALL_ACT:
|
||||||
|
tables, err := nl.ParseRouteAttr(datum.Value)
|
||||||
|
if err != nil {
|
||||||
|
return detailed, err
|
||||||
|
}
|
||||||
|
matchall.Actions, err = parseActions(tables)
|
||||||
|
if err != nil {
|
||||||
|
return detailed, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return detailed, nil
|
||||||
|
}
|
||||||
|
|
||||||
func AlignToAtm(size uint) uint {
|
func AlignToAtm(size uint) uint {
|
||||||
var linksize, cells int
|
var linksize, cells int
|
||||||
cells = int(size / nl.ATM_CELL_PAYLOAD)
|
cells = int(size / nl.ATM_CELL_PAYLOAD)
|
||||||
|
|
|
@ -168,13 +168,13 @@ func TestAdvancedFilterAddDel(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
u32SelKeys := []TcU32Key{
|
u32SelKeys := []TcU32Key{
|
||||||
TcU32Key{
|
{
|
||||||
Mask: 0xff,
|
Mask: 0xff,
|
||||||
Val: 80,
|
Val: 80,
|
||||||
Off: 20,
|
Off: 20,
|
||||||
OffMask: 0,
|
OffMask: 0,
|
||||||
},
|
},
|
||||||
TcU32Key{
|
{
|
||||||
Mask: 0xffff,
|
Mask: 0xffff,
|
||||||
Val: 0x146ca,
|
Val: 0x146ca,
|
||||||
Off: 32,
|
Off: 32,
|
||||||
|
@ -546,13 +546,11 @@ func TestFilterU32BpfAddDel(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFilterClsActBpfAddDel(t *testing.T) {
|
func setupLinkForTestWithQdisc(t *testing.T, linkName string) (Qdisc, Link) {
|
||||||
tearDown := setUpNetlinkTest(t)
|
if err := LinkAdd(&Ifb{LinkAttrs{Name: linkName}}); err != nil {
|
||||||
defer tearDown()
|
|
||||||
if err := LinkAdd(&Ifb{LinkAttrs{Name: "foo"}}); err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
link, err := LinkByName("foo")
|
link, err := LinkByName(linkName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -568,8 +566,6 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
|
||||||
QdiscAttrs: attrs,
|
QdiscAttrs: attrs,
|
||||||
QdiscType: "clsact",
|
QdiscType: "clsact",
|
||||||
}
|
}
|
||||||
// This feature was added in kernel 4.5
|
|
||||||
minKernelRequired(t, 4, 5)
|
|
||||||
|
|
||||||
if err := QdiscAdd(qdisc); err != nil {
|
if err := QdiscAdd(qdisc); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -584,7 +580,17 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
|
||||||
if q, ok := qdiscs[0].(*GenericQdisc); !ok || q.Type() != "clsact" {
|
if q, ok := qdiscs[0].(*GenericQdisc); !ok || q.Type() != "clsact" {
|
||||||
t.Fatal("qdisc is the wrong type")
|
t.Fatal("qdisc is the wrong type")
|
||||||
}
|
}
|
||||||
|
return qdiscs[0], link
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterClsActBpfAddDel(t *testing.T) {
|
||||||
|
// This feature was added in kernel 4.5
|
||||||
|
minKernelRequired(t, 4, 5)
|
||||||
|
|
||||||
|
tearDown := setUpNetlinkTest(t)
|
||||||
|
defer tearDown()
|
||||||
|
|
||||||
|
qdisc, link := setupLinkForTestWithQdisc(t, "foo")
|
||||||
filterattrs := FilterAttrs{
|
filterattrs := FilterAttrs{
|
||||||
LinkIndex: link.Attrs().Index,
|
LinkIndex: link.Attrs().Index,
|
||||||
Parent: HANDLE_MIN_EGRESS,
|
Parent: HANDLE_MIN_EGRESS,
|
||||||
|
@ -643,7 +649,7 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
|
||||||
if err := QdiscDel(qdisc); err != nil {
|
if err := QdiscDel(qdisc); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
qdiscs, err = SafeQdiscList(link)
|
qdiscs, err := SafeQdiscList(link)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -651,3 +657,74 @@ func TestFilterClsActBpfAddDel(t *testing.T) {
|
||||||
t.Fatal("Failed to remove qdisc")
|
t.Fatal("Failed to remove qdisc")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFilterMatchAllAddDel(t *testing.T) {
|
||||||
|
// This classifier was added in kernel 4.7
|
||||||
|
minKernelRequired(t, 4, 7)
|
||||||
|
|
||||||
|
tearDown := setUpNetlinkTest(t)
|
||||||
|
defer tearDown()
|
||||||
|
_, link := setupLinkForTestWithQdisc(t, "foo")
|
||||||
|
_, link2 := setupLinkForTestWithQdisc(t, "bar")
|
||||||
|
filter := &MatchAll{
|
||||||
|
FilterAttrs: FilterAttrs{
|
||||||
|
LinkIndex: link.Attrs().Index,
|
||||||
|
Parent: HANDLE_MIN_EGRESS,
|
||||||
|
Priority: 32000,
|
||||||
|
Protocol: unix.ETH_P_ALL,
|
||||||
|
},
|
||||||
|
Actions: []Action{
|
||||||
|
&MirredAction{
|
||||||
|
ActionAttrs: ActionAttrs{
|
||||||
|
Action: TC_ACT_STOLEN,
|
||||||
|
},
|
||||||
|
MirredAction: TCA_EGRESS_REDIR,
|
||||||
|
Ifindex: link2.Attrs().Index,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := FilterAdd(filter); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
filters, err := FilterList(link, HANDLE_MIN_EGRESS)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(filters) != 1 {
|
||||||
|
t.Fatal("Failed to add filter")
|
||||||
|
}
|
||||||
|
matchall, ok := filters[0].(*MatchAll)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("Filter is the wrong type")
|
||||||
|
}
|
||||||
|
|
||||||
|
if matchall.Priority != 32000 {
|
||||||
|
t.Fatal("Filter priority does not match")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(matchall.Actions) != 1 {
|
||||||
|
t.Fatal("Filter has no actions")
|
||||||
|
}
|
||||||
|
|
||||||
|
mirredAction, ok := matchall.Actions[0].(*MirredAction)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("Action does not match")
|
||||||
|
}
|
||||||
|
|
||||||
|
if mirredAction.Ifindex != link2.Attrs().Index {
|
||||||
|
t.Fatal("Action ifindex does not match")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := FilterDel(filter); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
filters, err = FilterList(link, HANDLE_MIN_EGRESS)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(filters) != 0 {
|
||||||
|
t.Fatal("Failed to remove filter")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -673,3 +673,10 @@ const (
|
||||||
TCA_FW_MASK
|
TCA_FW_MASK
|
||||||
TCA_FW_MAX = TCA_FW_MASK
|
TCA_FW_MAX = TCA_FW_MASK
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TCA_MATCHALL_UNSPEC = iota
|
||||||
|
TCA_MATCHALL_CLASSID
|
||||||
|
TCA_MATCHALL_ACT
|
||||||
|
TCA_MATCHALL_FLAGS
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue